summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Chick <tim.chick@csr.com>2009-08-24 15:49:00 +0100
committerTim Chick <tim.chick@csr.com>2009-08-24 15:49:00 +0100
commitb72fe11abaddfa27c9cf7e3f602a014068db4ff9 (patch)
tree19651b941cdf979b4efc183a4357fecfaf597f70
downloadunifi-105x-b72fe11abaddfa27c9cf7e3f602a014068db4ff9.tar.gz
Initial check in. The standard CSR UniFi 6.1 release code from unifi_linux_oss_6_1_147.tar.gz
-rw-r--r--unifi_hostsw_linux_147/oska/.buildid1
-rw-r--r--unifi_hostsw_linux_147/oska/Doxyfile1237
-rw-r--r--unifi_hostsw_linux_147/oska/LICENSE.txt39
-rw-r--r--unifi_hostsw_linux_147/oska/README49
-rw-r--r--unifi_hostsw_linux_147/oska/README-BETA-RELEASE10
-rw-r--r--unifi_hostsw_linux_147/oska/html/all_8h-source.html34
-rw-r--r--unifi_hostsw_linux_147/oska/html/alloc_8h-source.html43
-rw-r--r--unifi_hostsw_linux_147/oska/html/doxygen.css169
-rw-r--r--unifi_hostsw_linux_147/oska/html/doxygen.pngbin0 -> 1576 bytes
-rw-r--r--unifi_hostsw_linux_147/oska/html/files.html24
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__alloc.html169
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__mutex.html158
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__print.html194
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__semaphore.html132
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__spinlock.html216
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__thread.html236
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__time.html130
-rw-r--r--unifi_hostsw_linux_147/oska/html/group__util.html94
-rw-r--r--unifi_hostsw_linux_147/oska/html/index.html23
-rw-r--r--unifi_hostsw_linux_147/oska/html/modules.html23
-rw-r--r--unifi_hostsw_linux_147/oska/html/mutex_8h-source.html43
-rw-r--r--unifi_hostsw_linux_147/oska/html/print_8h-source.html48
-rw-r--r--unifi_hostsw_linux_147/oska/html/semaphore_8h-source.html43
-rw-r--r--unifi_hostsw_linux_147/oska/html/spinlock_8h-source.html45
-rw-r--r--unifi_hostsw_linux_147/oska/html/thread_8h-source.html47
-rw-r--r--unifi_hostsw_linux_147/oska/html/time_8h-source.html41
-rw-r--r--unifi_hostsw_linux_147/oska/html/util_8h-source.html39
-rw-r--r--unifi_hostsw_linux_147/oska/include/linux/kernel-compat.h157
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/all.h50
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/alloc.h82
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/mutex.h65
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/print.h79
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/semaphore.h63
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/spinlock.h79
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/thread.h100
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/time.h64
-rw-r--r--unifi_hostsw_linux_147/oska/include/oska/util.h49
-rw-r--r--unifi_hostsw_linux_147/oska/linux/Kbuild8
-rw-r--r--unifi_hostsw_linux_147/oska/linux/Makefile37
-rw-r--r--unifi_hostsw_linux_147/oska/linux/alloc.h36
-rwxr-xr-xunifi_hostsw_linux_147/oska/linux/build17
-rw-r--r--unifi_hostsw_linux_147/oska/linux/compat.c54
-rw-r--r--unifi_hostsw_linux_147/oska/linux/config.arm-linux.mk8
-rw-r--r--unifi_hostsw_linux_147/oska/linux/config.generic.mk24
-rw-r--r--unifi_hostsw_linux_147/oska/linux/mutex.h35
-rw-r--r--unifi_hostsw_linux_147/oska/linux/print.c48
-rw-r--r--unifi_hostsw_linux_147/oska/linux/print.h19
-rw-r--r--unifi_hostsw_linux_147/oska/linux/semaphore.h33
-rw-r--r--unifi_hostsw_linux_147/oska/linux/spinlock.h43
-rw-r--r--unifi_hostsw_linux_147/oska/linux/thread.c66
-rw-r--r--unifi_hostsw_linux_147/oska/linux/thread.h38
-rw-r--r--unifi_hostsw_linux_147/oska/linux/time.h32
-rw-r--r--unifi_hostsw_linux_147/oska/linux/util.h25
-rwxr-xr-xunifi_hostsw_linux_147/oska/scripts/lndir39
-rw-r--r--unifi_hostsw_linux_147/sdioemb/.buildid1
-rw-r--r--unifi_hostsw_linux_147/sdioemb/Doxyfile1237
-rw-r--r--unifi_hostsw_linux_147/sdioemb/Kbuild92
-rw-r--r--unifi_hostsw_linux_147/sdioemb/LICENSE.txt39
-rw-r--r--unifi_hostsw_linux_147/sdioemb/Makefile68
-rw-r--r--unifi_hostsw_linux_147/sdioemb/README57
-rw-r--r--unifi_hostsw_linux_147/sdioemb/README-BETA-RELEASE10
-rwxr-xr-xunifi_hostsw_linux_147/sdioemb/build17
-rw-r--r--unifi_hostsw_linux_147/sdioemb/cards/Kbuild6
-rw-r--r--unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a.c440
-rw-r--r--unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a_lx.c18
-rw-r--r--unifi_hostsw_linux_147/sdioemb/config.arm-linux.mk8
-rw-r--r--unifi_hostsw_linux_147/sdioemb/config.debug.mk4
-rw-r--r--unifi_hostsw_linux_147/sdioemb/config.generic.mk24
-rw-r--r--unifi_hostsw_linux_147/sdioemb/fdrv_uif_lx.c414
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/annotated.html25
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/bug.html27
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/cspi_8h-source.html55
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/deprecated.html17
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/doxygen.css169
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/doxygen.pngbin0 -> 1576 bytes
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/files.html37
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/functions.html102
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/functions_vars.html102
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/group__config.html213
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/group__fdriver.html1598
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/group__libsdio.html1357
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/group__registers.html257
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/group__sdriver.html574
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/index.html15
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/libsdio_8h-source.html96
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/libsdio__internal_8h-source.html55
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/modules.html20
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/pages.html19
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdd__test_8h-source.html52
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio_8h-source.html127
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio__api_8h-source.html201
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio__bt__a_8h-source.html126
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio__cis_8h-source.html40
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio__config_8h-source.html57
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio__csr_8h-source.html60
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio__event__log_8h-source.html128
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/sdio__layer_8h-source.html133
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__api_8h-source.html93
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__imx27_8h-source.html99
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__imx27__lx_8h-source.html33
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__imx31_8h-source.html99
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__imx31__lx_8h-source.html33
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x_8h-source.html83
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x__lx_8h-source.html59
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__shc_8h-source.html132
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/slot__spi__lx_8h-source.html32
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structcspi__cmd__resp.html121
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structsdio__card__io__ops.html39
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd.html265
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd__resp.html97
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structsdio__dev.html320
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structsdio__func__driver.html245
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structsdio__id__table.html126
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structsdio__slot.html519
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/structslot__caps.html100
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/uif_8h-source.html54
-rw-r--r--unifi_hostsw_linux_147/sdioemb/html/unionsdio__response.html42
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/linux/sdioemb/uif.h41
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/cspi.h62
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/libsdio.h388
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio.h114
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_api.h488
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_bt_a.h113
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_cis.h27
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_csr.h134
-rw-r--r--unifi_hostsw_linux_147/sdioemb/include/sdioemb/slot_api.h232
-rw-r--r--unifi_hostsw_linux_147/sdioemb/libsdio/Makefile35
-rw-r--r--unifi_hostsw_linux_147/sdioemb/libsdio/libsdio.c236
-rw-r--r--unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_async.c165
-rw-r--r--unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_internal.h42
-rwxr-xr-xunifi_hostsw_linux_147/sdioemb/scripts/lndir39
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_card.c548
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_cis.c101
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_cmd.c180
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_config.h105
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_core.c278
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_cspi.c225
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_event_log.c292
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_event_log.h115
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_func.c308
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_int.c107
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_io.c443
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_layer.h120
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_lx.c145
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_os_event_log_lx.c153
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_pm.c135
-rw-r--r--unifi_hostsw_linux_147/sdioemb/sdio_slot.c293
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx27.h86
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.c547
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.h20
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx27ads_lx.c141
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx31.h86
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.c602
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.h20
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_imx31ads_lx.c162
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_pxa27x.h70
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.c563
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.h46
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_sharp_cxx00.c113
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_shc.h119
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_shc_pci_lx.c904
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_spi_lx.c734
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_spi_lx.h19
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_ushc_lx.c538
-rw-r--r--unifi_hostsw_linux_147/sdioemb/slot_zeus_lx.c172
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/000_card_info.c100
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/001_block_size.c77
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/002_cmd52.c53
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/003_cmd52_async.c93
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/004_interrupt.c105
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/005_int_mask.c113
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/006_cmd53.c114
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/Makefile33
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/sdd_test.c195
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tests/sdd_test.h39
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tools/Makefile54
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tools/sdio-cmd52.c59
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tools/sdio-dump-cis.c156
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tools/sdio-freq-ctrl.c33
-rwxr-xr-xunifi_hostsw_linux_147/sdioemb/tools/sdio-log-decode621
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tools/sdio-reinsert.c32
-rw-r--r--unifi_hostsw_linux_147/sdioemb/tools/sdio-set-bus-width.c38
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/INSTALL.fc104
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/LICENSE.txt39
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/README40
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/common/driver/conversions.h108
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/common/driver/signals.h134
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/common/driver/sigs.h2230
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/common/driver/unifi.h384
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_types.h46
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_udi.h49
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/common/driver/unifiversion.h27
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/card.h97
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.c2700
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.h558
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_intr.c2262
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_mem.c1301
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.c715
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.h452
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper_private.h194
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/download.c1238
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/packing.c6904
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/placeholder.txt0
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/send.c325
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/signals.c1298
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.c447
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.h54
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/udi.c122
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/unifi_signal_names.c185
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/unifihw.h62
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.c715
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.h108
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/abstractions/osa.h534
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.c199
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.h91
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm.h242
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm_types.h412
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/hostio/hip_fsm_types.h517
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/sme_trace/sme_trace.h242
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_events.h2150
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_types.h678
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/bt_sap/bt_sap.h51
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/dbg_sap/dbg_sap.h33
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap.h117
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap_remote_sme_interface.h36
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap.h88
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap_remote_sme_interface.h36
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/lib_sme/sme/sme_top_level_fsm/sme.h142
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/Android.mk76
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Kbuild287
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Makefile69
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/bh.c605
-rwxr-xr-xunifi_hostsw_linux_147/unifi-linux/os_linux/driver/build17
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.3dlabs.mk20
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.android-arm.mk9
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.arm-linux.mk8
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.generic.mk41
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/data_tx.c138
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/drv.c1773
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/firmware.c206
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/indications.c101
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/inet.c82
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/io.c706
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/monitor.c453
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/netdev.c1699
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os.c369
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os_version.h23
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_support.h47
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_types.h149
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/putest.c286
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_emb.c541
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Kbuild24
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Makefile27
-rwxr-xr-xunifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/build17
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/config.generic.mk25
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_lx.c983
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_sdio_api.h58
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc.c587
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc_fs.c221
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mobstor.c1043
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_stubs.c54
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.c799
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.h42
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_remoteserver_to_sme_interface.c1074
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_mgt_sap.c269
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_proxy.c49
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_sys_sap.c262
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.c213
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.h31
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.c344
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.h40
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_remoteserver_to_sme_interface.c328
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_mgt.c1026
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/autojoin.c1580
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mib.c682
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mlme.c474
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/scan.c462
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/sme_native.c392
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/unifi_native.h282
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/wext.c3246
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_osa.c168
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_sys.c652
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_wext.c2455
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/ul_int.c553
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_clients.h126
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_config.h41
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_dbg.c105
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_os.h164
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_priv.h511
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.c771
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.h179
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_wext.h120
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifiio.h292
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/driver/wext_events.c251
-rwxr-xr-xunifi_hostsw_linux_147/unifi-linux/os_linux/scripts/fc4install107
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/Makefile62
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/README11
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/getsubopt.c92
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/hotplug52
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/unififw79
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/genmacmib.c291
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/mibquery.c421
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/prmib.c287
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.c411
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.h80
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config.c682
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.c336
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.h35
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_manager.c340
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_mib.c431
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest.c198
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.c190
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.h30
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_qos.c346
-rwxr-xr-xunifi_hostsw_linux_147/unifi-linux/os_linux/tools/unififw117
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.5.11_csr.patch128
-rw-r--r--unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.6.8_csr.patch109
-rw-r--r--unifi_hostsw_linux_147/versions.txt3
318 files changed, 89877 insertions, 0 deletions
diff --git a/unifi_hostsw_linux_147/oska/.buildid b/unifi_hostsw_linux_147/oska/.buildid
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/.buildid
@@ -0,0 +1 @@
+4
diff --git a/unifi_hostsw_linux_147/oska/Doxyfile b/unifi_hostsw_linux_147/oska/Doxyfile
new file mode 100644
index 0000000..2bbc221
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/Doxyfile
@@ -0,0 +1,1237 @@
+# Doxyfile 1.4.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = oska
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = include/oska/
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 1
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = __OSKA_API_DOC
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/unifi_hostsw_linux_147/oska/LICENSE.txt b/unifi_hostsw_linux_147/oska/LICENSE.txt
new file mode 100644
index 0000000..ca19f80
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/LICENSE.txt
@@ -0,0 +1,39 @@
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+Except as contained in this notice, the names of above-listed
+copyright holders and the names of any contributors shall not be used
+in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 (or later) as published
+by the Free Software Foundation.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from this file, or you compile this file
+and link it with other works to produce a work based on this file,
+this file does not by itself cause the resulting work to be covered by
+the GNU General Public License. However the source code for this file
+must still be made available in accordance with section (3) of the GNU
+General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
diff --git a/unifi_hostsw_linux_147/oska/README b/unifi_hostsw_linux_147/oska/README
new file mode 100644
index 0000000..5ce872e
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/README
@@ -0,0 +1,49 @@
+Generating the API documention
+------------------------------
+
+1. Generate the API documentation using the doxygen tool.
+
+ $ doxygen
+
+ The documentation will be generated as HTML in the html/ directory.
+
+Building and installing on Linux
+--------------------------------
+
+1. Build the module using the 'generic' configuration.
+
+ $ linux/build generic
+
+3. Install the module.
+
+ $ sudo linux/build generic install
+
+Available configurations:
+
+generic Host running Linux kernel 2.6.x
+arm-linux arm-linux target running 2.6.x (must specify KDIR)
+
+These configurations are specified in makefile fragments named
+config.<config>.mk.
+
+Useful variables include:
+
+ Variable Description Default
+ KDIR path to kernel source tree /lib/modules/`uname -r`/build
+ ARCH kernel architecture (e.g., ARM) unset
+ CROSS_COMPILE cross compiler prefix (e.g., arm-linux-) unset
+ O Kbuild's O (output directory) option unset
+ V Kbuild's V (verbosity) option unset
+ prefix Installation tree prefix /usr/local
+
+Additional configurations can be created to set any required variables
+before including the appropriate generic configuration. For example,
+for an arm-linux build (with the kernel in ~/work/linux-2.6.16.28):
+
+ KDIR := $(HOME)/work/linux-2.6.16.28
+
+ include config.arm-linux.mk
+
+Variables can also be specified on the command line.
+
+ $ ./build generic V=1
diff --git a/unifi_hostsw_linux_147/oska/README-BETA-RELEASE b/unifi_hostsw_linux_147/oska/README-BETA-RELEASE
new file mode 100644
index 0000000..b809c30
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/README-BETA-RELEASE
@@ -0,0 +1,10 @@
+Use of beta release software is at your own risk. This software is
+provided "as is," and CSR cautions users to determine for themselves
+the suitability of using the beta version of this software. CSR makes
+no warranty or representation whatsoever of merchantability or
+fitness of the product for any particular purpose or use. In no event
+shall CSR be liable for any consequential, incidental or special
+damages whatsoever arising out of the use of or inability to use this
+software, even if the user has advised CSR of the possibility of such
+damages. This software is for you alone, and is not to be
+redistributed.
diff --git a/unifi_hostsw_linux_147/oska/html/all_8h-source.html b/unifi_hostsw_linux_147/oska/html/all_8h-source.html
new file mode 100644
index 0000000..30e5ffe
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/all_8h-source.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/all.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/all.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- all functions</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_ALL_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_ALL_H</span>
+00011 <span class="preprocessor"></span>
+00041 <span class="preprocessor">#include &lt;oska/alloc.h&gt;</span>
+00042 <span class="preprocessor">#include &lt;oska/mutex.h&gt;</span>
+00043 <span class="preprocessor">#include &lt;oska/print.h&gt;</span>
+00044 <span class="preprocessor">#include &lt;oska/semaphore.h&gt;</span>
+00045 <span class="preprocessor">#include &lt;oska/spinlock.h&gt;</span>
+00046 <span class="preprocessor">#include &lt;oska/thread.h&gt;</span>
+00047 <span class="preprocessor">#include &lt;oska/time.h&gt;</span>
+00048 <span class="preprocessor">#include &lt;oska/util.h&gt;</span>
+00049
+00050 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_ALL_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/alloc_8h-source.html b/unifi_hostsw_linux_147/oska/html/alloc_8h-source.html
new file mode 100644
index 0000000..a453ab7
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/alloc_8h-source.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/alloc.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/alloc.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- memory allocation</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_ALLOC_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_ALLOC_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00013 <span class="preprocessor"></span>
+00038 <span class="keywordtype">void</span> *<a class="code" href="group__alloc.html#ga0">os_alloc</a>(size_t size);
+00039
+00049 <span class="keywordtype">void</span> <a class="code" href="group__alloc.html#ga1">os_free</a>(<span class="keywordtype">void</span> *ptr);
+00050
+00061 <span class="keywordtype">void</span> *<a class="code" href="group__alloc.html#ga2">os_alloc_big</a>(size_t size);
+00062
+00072 <span class="keywordtype">void</span> <a class="code" href="group__alloc.html#ga3">os_free_big</a>(<span class="keywordtype">void</span> *ptr);
+00073
+00074 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00075
+00076 <span class="preprocessor">#ifdef linux</span>
+00077 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/alloc.h&gt;</span>
+00078 <span class="preprocessor">#else</span>
+00079 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/alloc.h&gt; not provided for this OS</span>
+00080 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00081 <span class="preprocessor"></span>
+00082 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_ALLOC_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/doxygen.css b/unifi_hostsw_linux_147/oska/html/doxygen.css
new file mode 100644
index 0000000..a89dd24
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/doxygen.css
@@ -0,0 +1,169 @@
+H1 {
+ text-align: center;
+ font-family: Arial, Helvetica, sans-serif;
+}
+H2 {
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+CAPTION { font-weight: bold }
+DIV.qindex { width: 100%;
+ background-color: #eeeeff;
+ border: 4px solid #eeeeff;
+ text-align: center;
+ margin-bottom: 2px
+}
+A.qindex { text-decoration: none; font-weight: bold; color: #0000ee }
+A.qindex:visited { text-decoration: none; font-weight: bold; color: #0000ee }
+A.qindex:hover { text-decoration: none; background-color: #ddddff }
+A.qindexHL { text-decoration: none; font-weight: bold;
+ background-color: #6666cc;
+ color: #ffffff
+ }
+A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { font-weight: bold }
+A.code { text-decoration: none; font-weight: normal; color: #4444ee }
+A.codeRef { font-weight: normal; color: #4444ee }
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+DIV.fragment {
+ width: 98%;
+ border: 1px solid #CCCCCC;
+ background-color: #f5f5f5;
+ padding-left: 4px;
+ margin: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+TD.md { background-color: #f2f2ff; font-weight: bold; }
+TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; }
+TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; }
+DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
+BODY {
+ background: white;
+ color: black;
+ margin-right: 20px;
+ margin-left: 20px;
+}
+TD.indexkey {
+ background-color: #eeeeff;
+ font-weight: bold;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px
+}
+TD.indexvalue {
+ background-color: #eeeeff;
+ font-style: italic;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px
+}
+TR.memlist {
+ background-color: #f0f0f0;
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword { color: #008000 }
+SPAN.keywordtype { color: #604020 }
+SPAN.keywordflow { color: #e08000 }
+SPAN.comment { color: #800000 }
+SPAN.preprocessor { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral { color: #008080 }
+.mdTable {
+ border: 1px solid #868686;
+ background-color: #f2f2ff;
+}
+.mdRow {
+ padding: 8px 20px;
+}
+.mdescLeft {
+ font-size: smaller;
+ font-family: Arial, Helvetica, sans-serif;
+ background-color: #FAFAFA;
+ padding-left: 8px;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+}
+.mdescRight {
+ font-size: smaller;
+ font-family: Arial, Helvetica, sans-serif;
+ font-style: italic;
+ background-color: #FAFAFA;
+ padding-left: 4px;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+ padding-bottom: 0px;
+ padding-right: 8px;
+}
+.memItemLeft {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-style: solid;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+}
+.memItemRight {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-style: solid;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+}
+.search { color: #0000ee;
+ font-weight: bold;
+}
+FORM.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #eeeeff;
+}
+TD.tiny { font-size: 75%;
+}
diff --git a/unifi_hostsw_linux_147/oska/html/doxygen.png b/unifi_hostsw_linux_147/oska/html/doxygen.png
new file mode 100644
index 0000000..9da55f9
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/doxygen.png
Binary files differ
diff --git a/unifi_hostsw_linux_147/oska/html/files.html b/unifi_hostsw_linux_147/oska/html/files.html
new file mode 100644
index 0000000..5c99a9a
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/files.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: File Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindexHL" href="files.html">File&nbsp;List</a></div>
+<h1>oska File List</h1>Here is a list of all documented files with brief descriptions:<table>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>all.h</b> <a href="all_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>alloc.h</b> <a href="alloc_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>mutex.h</b> <a href="mutex_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>print.h</b> <a href="print_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>semaphore.h</b> <a href="semaphore_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>spinlock.h</b> <a href="spinlock_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>thread.h</b> <a href="thread_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>time.h</b> <a href="time_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/<b>util.h</b> <a href="util_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__alloc.html b/unifi_hostsw_linux_147/oska/html/group__alloc.html
new file mode 100644
index 0000000..9eca752
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__alloc.html
@@ -0,0 +1,169 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Memory allocation</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Memory allocation</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>void *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__alloc.html#ga0">os_alloc</a> (size_t size)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__alloc.html#ga1">os_free</a> (void *ptr)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__alloc.html#ga2">os_alloc_big</a> (size_t size)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__alloc.html#ga3">os_free_big</a> (void *ptr)</td></tr>
+
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga0" doxytag="alloc.h::os_alloc" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void* os_alloc </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">size_t&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>size</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Allocate a buffer of memory from the heap (or similar) and zero it.<p>
+The allocated memory will be physically contiguous and therefore suitable for DMA.<p>
+This is intended for small size allocations less than a page; larger, multi-page allocations are permitted but should be avoided. See <a class="el" href="group__alloc.html#ga2">os_alloc_big()</a> for an alternative for large allocations.<p>
+The memory should be freed with <a class="el" href="group__alloc.html#ga1">os_free()</a>.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>size</em>&nbsp;</td><td>memory size to allocate in octets.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>pointer to the allocated memory; or NULL if no memory could be allocated. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="alloc.h::os_alloc_big" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void* os_alloc_big </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">size_t&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>size</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Allocate memory for large (multi-page) buffers.<p>
+The allocated memory is <em>not</em> zeroed. It may not be physically contiguous and is <em>not</em> suitable for DMA.<p>
+The memory should be freed with <a class="el" href="group__alloc.html#ga3">os_free_big()</a>. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="alloc.h::os_free" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_free </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">void *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>ptr</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Free memory allocated with <a class="el" href="group__alloc.html#ga0">os_alloc()</a>.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>ptr</em>&nbsp;</td><td>pointer to the buffer to free. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="alloc.h::os_free_big" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_free_big </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">void *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>ptr</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Free memory allocated with <a class="el" href="group__alloc.html#ga2">os_alloc_big()</a>.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>ptr</em>&nbsp;</td><td>pointer to the buffer to free. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__mutex.html b/unifi_hostsw_linux_147/oska/html/group__mutex.html
new file mode 100644
index 0000000..46e643f
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__mutex.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Mutexes</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Mutexes</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef implementation_defined&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__mutex.html#ga0">os_mutex_t</a></td></tr>
+
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__mutex.html#ga1">os_mutex_init</a> (<a class="el" href="group__mutex.html#ga0">os_mutex_t</a> *mutex)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__mutex.html#ga2">os_mutex_lock</a> (<a class="el" href="group__mutex.html#ga0">os_mutex_t</a> *mutex)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__mutex.html#ga3">os_mutex_unlock</a> (<a class="el" href="group__mutex.html#ga0">os_mutex_t</a> *mutex)</td></tr>
+
+</table>
+<hr><h2>Typedef Documentation</h2>
+<a class="anchor" name="ga0" doxytag="mutex.h::os_mutex_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef implementation_defined <a class="el" href="group__mutex.html#ga0">os_mutex_t</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Implementation defined mutex object. </td>
+ </tr>
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga1" doxytag="mutex.h::os_mutex_init" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_mutex_init </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__mutex.html#ga0">os_mutex_t</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>mutex</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Initialize a mutex.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>mutex</em>&nbsp;</td><td>mutex to initialize. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="mutex.h::os_mutex_lock" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_mutex_lock </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__mutex.html#ga0">os_mutex_t</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>mutex</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Lock a mutex.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>mutex</em>&nbsp;</td><td>the mutex to lock. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="mutex.h::os_mutex_unlock" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_mutex_unlock </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__mutex.html#ga0">os_mutex_t</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>mutex</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Unlock a mutex.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>mutex</em>&nbsp;</td><td>the mutex to unlock. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__print.html b/unifi_hostsw_linux_147/oska/html/group__print.html
new file mode 100644
index 0000000..9ac3c9c
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__print.html
@@ -0,0 +1,194 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Console or log output</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Console or log output</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>enum &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__print.html#ga2">os_print_level</a> { <br>
+&nbsp;&nbsp;<b>OS_PRINT_ERROR</b>,
+<br>
+&nbsp;&nbsp;<b>OS_PRINT_WARNING</b>,
+<br>
+&nbsp;&nbsp;<b>OS_PRINT_INFO</b>,
+<br>
+&nbsp;&nbsp;<b>OS_PRINT_DEBUG</b>
+<br>
+ }</td></tr>
+
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__print.html#ga0">os_print</a> (enum <a class="el" href="group__print.html#ga2">os_print_level</a> level, const char *prefix, const char *name, const char *format,...)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__print.html#ga1">os_vprint</a> (enum <a class="el" href="group__print.html#ga2">os_print_level</a> level, const char *prefix, const char *name, const char *format, va_list args)</td></tr>
+
+</table>
+<hr><h2>Enumeration Type Documentation</h2>
+<a class="anchor" name="ga2" doxytag="print.h::os_print_level" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> enum <a class="el" href="group__print.html#ga2">os_print_level</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Severity of a console or log message. </td>
+ </tr>
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga0" doxytag="print.h::os_print" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_print </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">enum <a class="el" href="group__print.html#ga2">os_print_level</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>level</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>prefix</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>name</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>format</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>...&nbsp;</td>
+ <td class="mdname" nowrap></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write a text message to a log or the console.<p>
+The c, d, p, s, and x conversion specifiers and the field length and pad character should be supported (e.g., %08x).<p>
+The message may be truncated if it's longer than 80 characters.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>level</em>&nbsp;</td><td>severity of the message. </td></tr>
+ <tr><td valign=top><em>prefix</em>&nbsp;</td><td>string to be prefixed to the message. </td></tr>
+ <tr><td valign=top><em>name</em>&nbsp;</td><td>the name of the device or subsystem producing the message (may be NULL). </td></tr>
+ <tr><td valign=top><em>format</em>&nbsp;</td><td>printf-style format string. </td></tr>
+ <tr><td valign=top><em>...</em>&nbsp;</td><td>arguments for <em>format</em>. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="print.h::os_vprint" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_vprint </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">enum <a class="el" href="group__print.html#ga2">os_print_level</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>level</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>prefix</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>name</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>format</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>va_list&nbsp;</td>
+ <td class="mdname" nowrap> <em>args</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write a text message to a log or the console.<p>
+A variant of <a class="el" href="group__print.html#ga0">os_print()</a> accepting a va_list for the <em>format</em> arguments.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>level</em>&nbsp;</td><td>severity of the message. </td></tr>
+ <tr><td valign=top><em>prefix</em>&nbsp;</td><td>string to be prefixed to the message. </td></tr>
+ <tr><td valign=top><em>name</em>&nbsp;</td><td>the name of the device or subsystem producing the message (may be NULL). </td></tr>
+ <tr><td valign=top><em>format</em>&nbsp;</td><td>printf-style format string. </td></tr>
+ <tr><td valign=top><em>args</em>&nbsp;</td><td>arguments for <em>format</em>. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__semaphore.html b/unifi_hostsw_linux_147/oska/html/group__semaphore.html
new file mode 100644
index 0000000..23ab7db
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__semaphore.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Semaphores</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Semaphores</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__semaphore.html#ga0">os_semaphore_init</a> (os_semaphore_t *sem)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__semaphore.html#ga1">os_semaphore_wait</a> (os_semaphore_t *sem)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__semaphore.html#ga2">os_semaphore_post</a> (os_semaphore_t *sem)</td></tr>
+
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga0" doxytag="semaphore.h::os_semaphore_init" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_semaphore_init </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">os_semaphore_t *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>sem</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Initialize a semaphore to zero.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>sem</em>&nbsp;</td><td>semaphore to initialize. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="semaphore.h::os_semaphore_post" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_semaphore_post </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">os_semaphore_t *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>sem</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Post an event to a semaphore, waking any threads waiting on it.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>sem</em>&nbsp;</td><td>semaphore to post to. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="semaphore.h::os_semaphore_wait" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_semaphore_wait </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">os_semaphore_t *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>sem</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Wait for an event to be posted to the semaphore.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>sem</em>&nbsp;</td><td>semaphore to wait on. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__spinlock.html b/unifi_hostsw_linux_147/oska/html/group__spinlock.html
new file mode 100644
index 0000000..1b73587
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__spinlock.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Spinlocks</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Spinlocks</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef implementation_defined&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a></td></tr>
+
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__spinlock.html#ga1">os_spinlock_init</a> (<a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *lock)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__spinlock.html#ga2">os_spinlock_destroy</a> (<a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *lock)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__spinlock.html#ga3">os_spinlock_lock_intsave</a> (<a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *lock, os_int_status_t *int_state)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__spinlock.html#ga4">os_spinlock_unlock_intrestore</a> (<a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *lock, os_int_status_t *int_state)</td></tr>
+
+</table>
+<hr><h2>Typedef Documentation</h2>
+<a class="anchor" name="ga0" doxytag="spinlock.h::os_spinlock_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef implementation_defined <a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Implementation defined spinlock object. </td>
+ </tr>
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga2" doxytag="spinlock.h::os_spinlock_destroy" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_spinlock_destroy </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>lock</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Destroy a spinlock, freeing any resources the OS may have allocated.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>lock</em>&nbsp;</td><td>pointer to the spinlock to destroy. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="spinlock.h::os_spinlock_init" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_spinlock_init </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>lock</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Initialize a spinlock.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>lock</em>&nbsp;</td><td>pointer to the spinlock to initialize. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="spinlock.h::os_spinlock_lock_intsave" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_spinlock_lock_intsave </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>lock</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>os_int_status_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>int_state</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Lock a spinlock and disable interrupts (after saving the interrupt state).<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>lock</em>&nbsp;</td><td>pointer to the spinlock to lock. </td></tr>
+ <tr><td valign=top><em>int_state</em>&nbsp;</td><td>for saved interrupt state. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="spinlock.h::os_spinlock_unlock_intrestore" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_spinlock_unlock_intrestore </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__spinlock.html#ga0">os_spinlock_t</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>lock</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>os_int_status_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>int_state</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Unlock a spinlock, restoring the prior interrupt state.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>lock</em>&nbsp;</td><td>spinlock to unlock. </td></tr>
+ <tr><td valign=top><em>int_state</em>&nbsp;</td><td>interrupt state to restore. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__thread.html b/unifi_hostsw_linux_147/oska/html/group__thread.html
new file mode 100644
index 0000000..eab75ec
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__thread.html
@@ -0,0 +1,236 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Threading</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Threading</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef implementation_defined&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__thread.html#ga0">os_thread_t</a></td></tr>
+
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__thread.html#ga1">os_thread_create</a> (<a class="el" href="group__thread.html#ga0">os_thread_t</a> *thread, const char *name, void(*func)(void *), void *arg)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__thread.html#ga2">os_thread_stop</a> (<a class="el" href="group__thread.html#ga0">os_thread_t</a> *thread, os_semaphore_t *sem)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__thread.html#ga3">os_thread_should_stop</a> (<a class="el" href="group__thread.html#ga0">os_thread_t</a> *thread)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__thread.html#ga4">os_try_suspend_thread</a> (<a class="el" href="group__thread.html#ga0">os_thread_t</a> *thread)</td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+Threading support depends on the semaphore API provided by &lt;oska/semaphore.h&gt; (see <a class="el" href="group__semaphore.html">Semaphores</a>). <hr><h2>Typedef Documentation</h2>
+<a class="anchor" name="ga0" doxytag="thread.h::os_thread_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef implementation_defined <a class="el" href="group__thread.html#ga0">os_thread_t</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Implementation defined thread object. </td>
+ </tr>
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga1" doxytag="thread.h::os_thread_create" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int os_thread_create </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__thread.html#ga0">os_thread_t</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>thread</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>name</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void(*&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>)(void *), </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>arg</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Create and start a thread.<p>
+The thread function should call <a class="el" href="group__thread.html#ga3">os_thread_should_stop()</a> and return when it returns true.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>thread</em>&nbsp;</td><td>pointer to OS-specific thread data. </td></tr>
+ <tr><td valign=top><em>name</em>&nbsp;</td><td>thread name. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>thread entry-point function. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>argument for func.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; negative error code otherwise. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="thread.h::os_thread_should_stop" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int os_thread_should_stop </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__thread.html#ga0">os_thread_t</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>thread</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return true if the thread should stop (as signalled by a call to <a class="el" href="group__thread.html#ga2">os_thread_stop()</a>).<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>thread</em>&nbsp;</td><td>the thread to check.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>true iff the thread should stop. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="thread.h::os_thread_stop" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_thread_stop </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__thread.html#ga0">os_thread_t</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>thread</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>os_semaphore_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>sem</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Stop a thread and wait for it to exit.<p>
+If <em>sem</em> is non-NULL it will be posted to awaken the thread. The thread will also be awakened if it's asleep (in a <a class="el" href="group__time.html#ga1">os_sleep_ms()</a> call for example).<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>thread</em>&nbsp;</td><td>the thread to stop. </td></tr>
+ <tr><td valign=top><em>sem</em>&nbsp;</td><td>a semaphore to post to awaken the thread, may be NULL.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve otherwise. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="thread.h::os_try_suspend_thread" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void os_try_suspend_thread </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__thread.html#ga0">os_thread_t</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>thread</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Try to suspend a thread.<p>
+This specifies a point where it is safe for a thread to be suspended.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>thread</em>&nbsp;</td><td>pointer to OS-specific thread data. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__time.html b/unifi_hostsw_linux_147/oska/html/group__time.html
new file mode 100644
index 0000000..d80cffc
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__time.html
@@ -0,0 +1,130 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Timing and delays</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Timing and delays</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>unsigned long&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__time.html#ga0">os_current_time_ms</a> (void)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__time.html#ga1">os_sleep_ms</a> (unsigned ms)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__time.html#ga2">os_delay_us</a> (unsigned us)</td></tr>
+
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga0" doxytag="time.h::os_current_time_ms" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> unsigned long os_current_time_ms </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">void&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return the current time (since an arbitrary point) in milliseconds.<p>
+The resolution depends on the OS but would typically be 10 ms or better.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Returns:</b></dt><dd>current time in ms. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="time.h::os_delay_us" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int os_delay_us </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">unsigned&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>us</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Delay a minimum length of time.<p>
+This may busy-wait and should not be used for long delays (use <a class="el" href="group__time.html#ga1">os_sleep_ms()</a> instead).<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>us</em>&nbsp;</td><td>minimum time to delay (in us). </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="time.h::os_sleep_ms" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int os_sleep_ms </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">unsigned&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>ms</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Sleep for a minimum length of time.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>ms</em>&nbsp;</td><td>minimum time to sleep (in ms). </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/group__util.html b/unifi_hostsw_linux_147/oska/html/group__util.html
new file mode 100644
index 0000000..28a2805
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/group__util.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Miscellaneous utilties</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Miscellaneous utilties</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__util.html#ga0">os_cpu_to_le16</a> (uint16_t x)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__util.html#ga1">os_le16_to_cpu</a> (uint16_t x)</td></tr>
+
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga0" doxytag="util.h::os_cpu_to_le16" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t os_cpu_to_le16 </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">uint16_t&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>x</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return a CPU (native) byte ordered 16-bit word in little endian byte order.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>x</em>&nbsp;</td><td>CPU ordered word.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>the word in little-endian byte order. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="util.h::os_le16_to_cpu" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t os_le16_to_cpu </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">uint16_t&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>x</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return a little endian byte ordered 16-bit word in CPU (native) byte order.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>x</em>&nbsp;</td><td>little endian word.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>the word in native byte order. </dd></dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/index.html b/unifi_hostsw_linux_147/oska/html/index.html
new file mode 100644
index 0000000..3a7f8cd
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/index.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Operating System Kernel Abstraction</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindexHL" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>Operating System Kernel Abstraction </h1>
+<p>
+<h2><a class="anchor" name="intro">
+Introduction</a></h2>
+The Operating System Kernel Abstraction (oska) is a software package providing an abstraction for various operating system kernel facilities for use by device drivers and other OS kernel software (e.g., SDIO stacks). Oska is modularized and intended to be a lightweight wrapper around an OSes interfaces.<h2><a class="anchor" name="modules">
+Modules</a></h2>
+Oska is organized into the modules, each of which has it's own header file providing the interface.<p>
+<ul>
+<li><a class="el" href="group__alloc.html">Memory allocation</a> &lt;oska/alloc.h&gt;</li><li><a class="el" href="group__mutex.html">Mutexes</a> &lt;oska/mutex.h&gt;</li><li><a class="el" href="group__print.html">Console output</a> &lt;oska/print.h&gt;</li><li><a class="el" href="group__semaphore.html">Semaphores</a> &lt;oska/semaphore.h&gt;</li><li><a class="el" href="group__spinlock.html">Spinlocks</a> &lt;oska/spinlock.h&gt;</li><li><a class="el" href="group__thread.html">Threading</a> &lt;oska/thread.h&gt;</li><li><a class="el" href="group__time.html">Timing and delays</a> &lt;oska/time.h&gt;</li><li><a class="el" href="group__util.html">Miscellaneous utilities</a> &lt;oska/util.h&gt;</li></ul>
+<p>
+An &lt;oska/all.h&gt; header is provided which includes all the above modules. <hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/modules.html b/unifi_hostsw_linux_147/oska/html/modules.html
new file mode 100644
index 0000000..4e7355f
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/modules.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: Module Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindexHL" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>oska Modules</h1>Here is a list of all modules:<ul>
+<li><a class="el" href="group__alloc.html">Memory allocation</a>
+<li><a class="el" href="group__mutex.html">Mutexes</a>
+<li><a class="el" href="group__print.html">Console or log output</a>
+<li><a class="el" href="group__semaphore.html">Semaphores</a>
+<li><a class="el" href="group__spinlock.html">Spinlocks</a>
+<li><a class="el" href="group__thread.html">Threading</a>
+<li><a class="el" href="group__time.html">Timing and delays</a>
+<li><a class="el" href="group__util.html">Miscellaneous utilties</a>
+</ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/mutex_8h-source.html b/unifi_hostsw_linux_147/oska/html/mutex_8h-source.html
new file mode 100644
index 0000000..f7474ee
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/mutex_8h-source.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/mutex.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/mutex.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- mutexes</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_MUTEX_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_MUTEX_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00013 <span class="preprocessor"></span>
+<a name="l00022"></a><a class="code" href="group__mutex.html#ga0">00022</a> <span class="keyword">typedef</span> implementation_defined <a class="code" href="group__mutex.html#ga0">os_mutex_t</a>;
+00023
+00033 <span class="keywordtype">void</span> <a class="code" href="group__mutex.html#ga1">os_mutex_init</a>(os_mutex_t *mutex);
+00034
+00044 <span class="keywordtype">void</span> <a class="code" href="group__mutex.html#ga2">os_mutex_lock</a>(os_mutex_t *mutex);
+00045
+00055 <span class="keywordtype">void</span> <a class="code" href="group__mutex.html#ga3">os_mutex_unlock</a>(os_mutex_t *mutex);
+00056
+00057 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00058
+00059 <span class="preprocessor">#ifdef linux</span>
+00060 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/mutex.h&gt;</span>
+00061 <span class="preprocessor">#else</span>
+00062 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/mutex.h&gt; not provided for this OS</span>
+00063 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00064 <span class="preprocessor"></span>
+00065 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_MUTEX_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/print_8h-source.html b/unifi_hostsw_linux_147/oska/html/print_8h-source.html
new file mode 100644
index 0000000..288b2d7
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/print_8h-source.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/print.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/print.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- console printing</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_PRINT_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_PRINT_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00013 <span class="preprocessor"></span>
+00036 <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga0">os_print</a>(<span class="keyword">enum</span> os_print_level level, <span class="keyword">const</span> <span class="keywordtype">char</span> *prefix, <span class="keyword">const</span> <span class="keywordtype">char</span> *name,
+00037 <span class="keyword">const</span> <span class="keywordtype">char</span> *format, ...);
+00038
+00056 <span class="keywordtype">void</span> <a class="code" href="group__print.html#ga1">os_vprint</a>(<span class="keyword">enum</span> os_print_level level, <span class="keyword">const</span> <span class="keywordtype">char</span> *prefix, <span class="keyword">const</span> <span class="keywordtype">char</span> *name,
+00057 <span class="keyword">const</span> <span class="keywordtype">char</span> *format, va_list args);
+00058
+00059 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00060
+<a name="l00066"></a><a class="code" href="group__print.html#ga2">00066</a> <span class="keyword">enum</span> <a class="code" href="group__print.html#ga2">os_print_level</a> {
+00067 OS_PRINT_ERROR,
+00068 OS_PRINT_WARNING,
+00069 OS_PRINT_INFO,
+00070 OS_PRINT_DEBUG,
+00071 };
+00072
+00073 <span class="preprocessor">#ifdef linux</span>
+00074 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/print.h&gt;</span>
+00075 <span class="preprocessor">#else</span>
+00076 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/print.h&gt; not provided for this OS</span>
+00077 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00078 <span class="preprocessor"></span>
+00079 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_PRINT_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/semaphore_8h-source.html b/unifi_hostsw_linux_147/oska/html/semaphore_8h-source.html
new file mode 100644
index 0000000..003ef0c
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/semaphore_8h-source.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/semaphore.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/semaphore.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- semaphores</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_SEMAPHORE_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_SEMAPHORE_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00013 <span class="preprocessor"></span>
+00020 <span class="keyword">typedef</span> implementation_defined os_semaphore_t;
+00021
+00031 <span class="keywordtype">void</span> <a class="code" href="group__semaphore.html#ga0">os_semaphore_init</a>(os_semaphore_t *sem);
+00032
+00042 <span class="keywordtype">void</span> <a class="code" href="group__semaphore.html#ga1">os_semaphore_wait</a>(os_semaphore_t *sem);
+00043
+00053 <span class="keywordtype">void</span> <a class="code" href="group__semaphore.html#ga2">os_semaphore_post</a>(os_semaphore_t *sem);
+00054
+00055 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00056
+00057 <span class="preprocessor">#ifdef linux</span>
+00058 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/semaphore.h&gt;</span>
+00059 <span class="preprocessor">#else</span>
+00060 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/semaphore.h&gt; not provided for this OS</span>
+00061 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00062 <span class="preprocessor"></span>
+00063 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_SEMAPHORE_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/spinlock_8h-source.html b/unifi_hostsw_linux_147/oska/html/spinlock_8h-source.html
new file mode 100644
index 0000000..a20c19a
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/spinlock_8h-source.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/spinlock.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/spinlock.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- spinlocks</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_SPINLOCK_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_SPINLOCK_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00013 <span class="preprocessor"></span>
+<a name="l00022"></a><a class="code" href="group__spinlock.html#ga0">00022</a> <span class="keyword">typedef</span> implementation_defined <a class="code" href="group__spinlock.html#ga0">os_spinlock_t</a>;
+00023
+00033 <span class="keywordtype">void</span> <a class="code" href="group__spinlock.html#ga1">os_spinlock_init</a>(os_spinlock_t *lock);
+00034
+00044 <span class="keywordtype">void</span> <a class="code" href="group__spinlock.html#ga2">os_spinlock_destroy</a>(os_spinlock_t *lock);
+00045
+00057 <span class="keywordtype">void</span> <a class="code" href="group__spinlock.html#ga3">os_spinlock_lock_intsave</a>(os_spinlock_t *lock, os_int_status_t *int_state);
+00058
+00069 <span class="keywordtype">void</span> <a class="code" href="group__spinlock.html#ga4">os_spinlock_unlock_intrestore</a>(os_spinlock_t *lock, os_int_status_t *int_state);
+00070
+00071 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00072
+00073 <span class="preprocessor">#ifdef linux</span>
+00074 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/spinlock.h&gt;</span>
+00075 <span class="preprocessor">#else</span>
+00076 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/spinlock.h&gt; not provided for this OS</span>
+00077 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00078 <span class="preprocessor"></span>
+00079 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_SPINLOCK_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/thread_8h-source.html b/unifi_hostsw_linux_147/oska/html/thread_8h-source.html
new file mode 100644
index 0000000..dc5c7ec
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/thread_8h-source.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/thread.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/thread.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- threading</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_THREAD_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_THREAD_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include &lt;oska/semaphore.h&gt;</span>
+00013
+00014 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00015 <span class="preprocessor"></span>
+<a name="l00027"></a><a class="code" href="group__thread.html#ga0">00027</a> <span class="keyword">typedef</span> implementation_defined <a class="code" href="group__thread.html#ga0">os_thread_t</a>;
+00028
+00046 <span class="keywordtype">int</span> <a class="code" href="group__thread.html#ga1">os_thread_create</a>(os_thread_t *thread, <span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keywordtype">void</span> (*func)(<span class="keywordtype">void</span> *), <span class="keywordtype">void</span> *arg);
+00047
+00064 <span class="keywordtype">void</span> <a class="code" href="group__thread.html#ga2">os_thread_stop</a>(os_thread_t *thread, os_semaphore_t *sem);
+00065
+00076 <span class="keywordtype">int</span> <a class="code" href="group__thread.html#ga3">os_thread_should_stop</a>(os_thread_t *thread);
+00077
+00090 <span class="keywordtype">void</span> <a class="code" href="group__thread.html#ga4">os_try_suspend_thread</a>(os_thread_t *thread);
+00091
+00092 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00093
+00094 <span class="preprocessor">#ifdef linux</span>
+00095 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/thread.h&gt;</span>
+00096 <span class="preprocessor">#else</span>
+00097 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/thread.h&gt; not provided for this OS</span>
+00098 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00099 <span class="preprocessor"></span>
+00100 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_THREAD_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/time_8h-source.html b/unifi_hostsw_linux_147/oska/html/time_8h-source.html
new file mode 100644
index 0000000..2d97b2a
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/time_8h-source.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/time.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/time.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- timing</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_TIME_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_TIME_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00013 <span class="preprocessor"></span>
+00029 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <a class="code" href="group__time.html#ga0">os_current_time_ms</a>(<span class="keywordtype">void</span>);
+00030
+00040 <span class="keywordtype">int</span> <a class="code" href="group__time.html#ga1">os_sleep_ms</a>(<span class="keywordtype">unsigned</span> ms);
+00041
+00054 <span class="keywordtype">int</span> <a class="code" href="group__time.html#ga2">os_delay_us</a>(<span class="keywordtype">unsigned</span> us);
+00055
+00056 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00057
+00058 <span class="preprocessor">#ifdef linux</span>
+00059 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/time.h&gt;</span>
+00060 <span class="preprocessor">#else</span>
+00061 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/time.h&gt; not provided for this OS</span>
+00062 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00063 <span class="preprocessor"></span>
+00064 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_TIME_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/html/util_8h-source.html b/unifi_hostsw_linux_147/oska/html/util_8h-source.html
new file mode 100644
index 0000000..f5a29fa
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/html/util_8h-source.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>oska: /home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/util.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="files.html">File&nbsp;List</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/oska-4/builds/oska-4/include/oska/util.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Operating system kernel abstraction -- misc. utility functions</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef __OSKA_UTIL_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define __OSKA_UTIL_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#ifdef __OSKA_API_DOC</span>
+00013 <span class="preprocessor"></span>
+00027 uint16_t <a class="code" href="group__util.html#ga0">os_cpu_to_le16</a>(uint16_t x);
+00028
+00039 uint16_t <a class="code" href="group__util.html#ga1">os_le16_to_cpu</a>(uint16_t x);
+00040
+00041 <span class="preprocessor">#endif </span><span class="comment">/* __OSKA_API_DOC */</span>
+00042
+00043 <span class="preprocessor">#ifdef linux</span>
+00044 <span class="preprocessor"></span><span class="preprocessor"># include &lt;../linux/util.h&gt;</span>
+00045 <span class="preprocessor">#else</span>
+00046 <span class="preprocessor"></span><span class="preprocessor"># error &lt;oska/util.h&gt; not provided for this OS</span>
+00047 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00048 <span class="preprocessor"></span>
+00049 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef __OSKA_UTIL_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:35 2008 for oska by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/oska/include/linux/kernel-compat.h b/unifi_hostsw_linux_147/oska/include/linux/kernel-compat.h
new file mode 100644
index 0000000..9cf7bd1
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/linux/kernel-compat.h
@@ -0,0 +1,157 @@
+/*
+ * Kernel version compatibility.
+ *
+ * Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Wherever possible compatible implementations of newer APIs are
+ * provided for older kernel versions.
+ */
+#ifndef __LINUX_KERNEL_COMPAT_H
+#define __LINUX_KERNEL_COMPAT_H
+
+#include <linux/version.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+
+/*
+ * linux/semaphore.h replaces asm/semaphore.h in 2.6.27.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+# include <asm/semaphore.h>
+#else
+# include <linux/semaphore.h>
+#endif
+
+/*
+ * Workqueue API changes in 2.6.20
+ *
+ * See http://lwn.net/Articles/211279/ for details.
+ *
+ * We deliberately don't provide the non-automatic release (NAR)
+ * variants as a simple compatible implementation is not possible.
+ * This shouldn't be a problem as all usage so far is to embed the
+ * struct work_struct into another struct and the NAR variants aren't
+ * useful in this case (see http://lwn.net/Articles/213149/).
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+
+#include <linux/workqueue.h>
+
+#undef INIT_WORK
+#define INIT_WORK(_work, _func) \
+ do { \
+ INIT_LIST_HEAD(&(_work)->entry); \
+ (_work)->pending = 0; \
+ PREPARE_WORK((_work), (_func), (_work)); \
+ init_timer(&(_work)->timer); \
+ } while(0)
+
+#undef DECLARE_WORK
+#define DECLARE_WORK(n, f) \
+ struct work_struct n = __WORK_INITIALIZER((n), (f), &(n))
+
+struct delayed_work {
+ struct work_struct work;
+};
+
+#define INIT_DELAYED_WORK(dw, fn) \
+ INIT_WORK(&(dw)->work, (fn))
+
+#define queue_delayed_work(wq, dw, delay) \
+ queue_delayed_work((wq), &(dw)->work, (delay))
+
+#define schedule_delayed_work(dw, delay) \
+ schedule_delayed_work(&(dw)->work, (delay))
+
+#define cancel_delayed_work(dw) \
+ cancel_delayed_work(&(dw)->work)
+
+#endif /* Linux kernel < 2.6.20 */
+
+/*
+ * cancel_work_sync() added in 2.6.22.
+ *
+ * This compat implementation is only suitable for work queued on the
+ * default workqueue.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
+
+static inline void cancel_work_sync(struct work_struct *work)
+{
+ flush_scheduled_work();
+}
+
+#endif /* Linux kernel < 2.6.22 */
+
+/*
+ * device_create()/class_device_create()
+ *
+ * device_create() gains a drvdata parameter in 2.6.27. Since all
+ * users of device_create() in CSR code don't use drvdata just ignore
+ * it.
+ *
+ * device_create() replaces class_device_create() in 2.6.21.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+
+#define device_create(class, parent, devt, drvdata, fmt, args...) \
+ class_device_create((class), (parent), (devt), NULL, (fmt), ## args)
+#define device_destroy(class, devt) \
+ class_device_destroy(class, devt)
+
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+
+#define device_create(class, parent, devt, drvdata, fmt, args...) \
+ device_create((class), (parent), (devt), (fmt), ## args)
+
+#endif /* Linux kernel < 2.6.26 */
+
+/*
+ * dev_name() and dev_set_name() added in 2.6.26.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
+
+static inline char *dev_name(struct device *dev)
+{
+ return dev->bus_id;
+}
+
+int dev_set_name(struct device *dev, const char *fmt, ...);
+
+#endif /* Linux kernel < 2.6.26 */
+
+/*
+ * class_find_device() in 2.6.25
+ */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+
+struct device *class_find_device(struct class *class, struct device *start,
+ void *data, int (*match)(struct device *, void *));
+
+#endif /* Linux kernel < 2.6.25 */
+
+/*
+ * 2.6.19 adds a bool type.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+
+typedef _Bool bool;
+enum {
+ false = 0,
+ true = 1
+};
+
+#endif /* Linux kernel < 2.6.19 */
+
+/*
+ * PCI_VENDOR_ID_CSR may not exist
+ */
+#ifndef PCI_VENDOR_ID_CSR
+# define PCI_VENDOR_ID_CSR 0x18e5
+#endif
+
+#endif /* #ifndef __LINUX_KERNEL_COMPAT_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/all.h b/unifi_hostsw_linux_147/oska/include/oska/all.h
new file mode 100644
index 0000000..d35895e
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/all.h
@@ -0,0 +1,50 @@
+/*
+ * Operating system kernel abstraction -- all functions
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_ALL_H
+#define __OSKA_ALL_H
+
+/**
+ * @mainpage Operating System Kernel Abstraction
+ *
+ * @section intro Introduction
+ *
+ * The Operating System Kernel Abstraction (oska) is a software
+ * package providing an abstraction for various operating system
+ * kernel facilities for use by device drivers and other OS kernel
+ * software (e.g., SDIO stacks). Oska is modularized and intended to
+ * be a lightweight wrapper around an OSes interfaces.
+ *
+ * @section modules Modules
+ *
+ * Oska is organized into the modules, each of which has it's own
+ * header file providing the interface.
+ *
+ * - \ref alloc "Memory allocation" <oska/alloc.h>
+ * - \ref mutex "Mutexes" <oska/mutex.h>
+ * - \ref print "Console output" <oska/print.h>
+ * - \ref semaphore "Semaphores" <oska/semaphore.h>
+ * - \ref spinlock "Spinlocks" <oska/spinlock.h>
+ * - \ref thread "Threading" <oska/thread.h>
+ * - \ref time "Timing and delays" <oska/time.h>
+ * - \ref util "Miscellaneous utilities" <oska/util.h>
+ *
+ * An <oska/all.h> header is provided which includes all the above
+ * modules.
+ */
+
+#include <oska/alloc.h>
+#include <oska/mutex.h>
+#include <oska/print.h>
+#include <oska/semaphore.h>
+#include <oska/spinlock.h>
+#include <oska/thread.h>
+#include <oska/time.h>
+#include <oska/util.h>
+
+#endif /* __OSKA_ALL_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/alloc.h b/unifi_hostsw_linux_147/oska/include/oska/alloc.h
new file mode 100644
index 0000000..b620c7f
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/alloc.h
@@ -0,0 +1,82 @@
+/*
+ * Operating system kernel abstraction -- memory allocation
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_ALLOC_H
+#define __OSKA_ALLOC_H
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup alloc Memory allocation
+ */
+
+/**
+ * Allocate a buffer of memory from the heap (or similar) and zero it.
+ *
+ * The allocated memory will be physically contiguous and therefore
+ * suitable for DMA.
+ *
+ * This is intended for small size allocations less than a page;
+ * larger, multi-page allocations are permitted but should be avoided.
+ * See os_alloc_big() for an alternative for large allocations.
+ *
+ * The memory should be freed with os_free().
+ *
+ * Callable from: thread context.
+ *
+ * @param size memory size to allocate in octets.
+ *
+ * @return pointer to the allocated memory; or NULL if no memory could
+ * be allocated.
+ *
+ * @ingroup alloc
+ */
+void *os_alloc(size_t size);
+
+/**
+ * Free memory allocated with os_alloc().
+ *
+ * Callable from: any context.
+ *
+ * @param ptr pointer to the buffer to free.
+ *
+ * @ingroup alloc
+ */
+void os_free(void *ptr);
+
+/**
+ * Allocate memory for large (multi-page) buffers.
+ *
+ * The allocated memory is \e not zeroed. It may not be physically
+ * contiguous and is \e not suitable for DMA.
+ *
+ * The memory should be freed with os_free_big().
+ *
+ * @ingroup alloc
+ */
+void *os_alloc_big(size_t size);
+
+/**
+ * Free memory allocated with os_alloc_big().
+ *
+ * Callable from: any context.
+ *
+ * @param ptr pointer to the buffer to free.
+ *
+ * @ingroup alloc
+ */
+void os_free_big(void *ptr);
+
+#endif /* __OSKA_API_DOC */
+
+#ifdef linux
+# include <../linux/alloc.h>
+#else
+# error <oska/alloc.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_ALLOC_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/mutex.h b/unifi_hostsw_linux_147/oska/include/oska/mutex.h
new file mode 100644
index 0000000..5d97652
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/mutex.h
@@ -0,0 +1,65 @@
+/*
+ * Operating system kernel abstraction -- mutexes
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_MUTEX_H
+#define __OSKA_MUTEX_H
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup mutex Mutexes
+ */
+
+/**
+ * Implementation defined mutex object.
+ *
+ * @ingroup mutex
+ */
+typedef implementation_defined os_mutex_t;
+
+/**
+ * Initialize a mutex.
+ *
+ * Callable from: thread context.
+ *
+ * @param mutex mutex to initialize.
+ *
+ * @ingroup mutex
+ */
+void os_mutex_init(os_mutex_t *mutex);
+
+/**
+ * Lock a mutex.
+ *
+ * Callable from: thread context.
+ *
+ * @param mutex the mutex to lock.
+ *
+ * @ingroup mutex
+ */
+void os_mutex_lock(os_mutex_t *mutex);
+
+/**
+ * Unlock a mutex.
+ *
+ * Callable from: thread context.
+ *
+ * @param mutex the mutex to unlock.
+ *
+ * @ingroup mutex
+ */
+void os_mutex_unlock(os_mutex_t *mutex);
+
+#endif /* __OSKA_API_DOC */
+
+#ifdef linux
+# include <../linux/mutex.h>
+#else
+# error <oska/mutex.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_MUTEX_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/print.h b/unifi_hostsw_linux_147/oska/include/oska/print.h
new file mode 100644
index 0000000..6afe5fd
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/print.h
@@ -0,0 +1,79 @@
+/*
+ * Operating system kernel abstraction -- console printing
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_PRINT_H
+#define __OSKA_PRINT_H
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup print Console or log output
+ */
+
+/**
+ * Write a text message to a log or the console.
+ *
+ * The c, d, p, s, and x conversion specifiers and the field length
+ * and pad character should be supported (e.g., \%08x).
+ *
+ * The message may be truncated if it's longer than 80 characters.
+ *
+ * Callable from: any context.
+ *
+ * @param level severity of the message.
+ * @param prefix string to be prefixed to the message.
+ * @param name the name of the device or subsystem producing the
+ * message (may be NULL).
+ * @param format printf-style format string.
+ * @param ... arguments for \a format.
+ *
+ * @ingroup print
+ */
+void os_print(enum os_print_level level, const char *prefix, const char *name,
+ const char *format, ...);
+
+/**
+ * Write a text message to a log or the console.
+ *
+ * A variant of os_print() accepting a va_list for the \a format
+ * arguments.
+ *
+ * Callable from: any context.
+ *
+ * @param level severity of the message.
+ * @param prefix string to be prefixed to the message.
+ * @param name the name of the device or subsystem producing the
+ * message (may be NULL).
+ * @param format printf-style format string.
+ * @param args arguments for \a format.
+ *
+ * @ingroup print
+ */
+void os_vprint(enum os_print_level level, const char *prefix, const char *name,
+ const char *format, va_list args);
+
+#endif /* __OSKA_API_DOC */
+
+/**
+ * Severity of a console or log message.
+ *
+ * @ingroup print
+ */
+enum os_print_level {
+ OS_PRINT_ERROR,
+ OS_PRINT_WARNING,
+ OS_PRINT_INFO,
+ OS_PRINT_DEBUG,
+};
+
+#ifdef linux
+# include <../linux/print.h>
+#else
+# error <oska/print.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_PRINT_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/semaphore.h b/unifi_hostsw_linux_147/oska/include/oska/semaphore.h
new file mode 100644
index 0000000..8f02807
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/semaphore.h
@@ -0,0 +1,63 @@
+/*
+ * Operating system kernel abstraction -- semaphores
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_SEMAPHORE_H
+#define __OSKA_SEMAPHORE_H
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup semaphore Semaphores
+ */
+
+/**
+ * Implementation defined semaphore object.
+ */
+typedef implementation_defined os_semaphore_t;
+
+/**
+ * Initialize a semaphore to zero.
+ *
+ * Callable from: thread context.
+ *
+ * @param sem semaphore to initialize.
+ *
+ * @ingroup semaphore
+ */
+void os_semaphore_init(os_semaphore_t *sem);
+
+/**
+ * Wait for an event to be posted to the semaphore.
+ *
+ * Callable from: thread context.
+ *
+ * @param sem semaphore to wait on.
+ *
+ * @ingroup semaphore
+ */
+void os_semaphore_wait(os_semaphore_t *sem);
+
+/**
+ * Post an event to a semaphore, waking any threads waiting on it.
+ *
+ * Callable from: any context.
+ *
+ * @param sem semaphore to post to.
+ *
+ * @ingroup semaphore
+ */
+void os_semaphore_post(os_semaphore_t *sem);
+
+#endif /* __OSKA_API_DOC */
+
+#ifdef linux
+# include <../linux/semaphore.h>
+#else
+# error <oska/semaphore.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_SEMAPHORE_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/spinlock.h b/unifi_hostsw_linux_147/oska/include/oska/spinlock.h
new file mode 100644
index 0000000..4c100ad
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/spinlock.h
@@ -0,0 +1,79 @@
+/*
+ * Operating system kernel abstraction -- spinlocks
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_SPINLOCK_H
+#define __OSKA_SPINLOCK_H
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup spinlock Spinlocks
+ */
+
+/**
+ * Implementation defined spinlock object.
+ *
+ * @ingroup spinlock
+ */
+typedef implementation_defined os_spinlock_t;
+
+/**
+ * Initialize a spinlock.
+ *
+ * Callable from: thread context.
+ *
+ * @param lock pointer to the spinlock to initialize.
+ *
+ * @ingroup spinlock
+ */
+void os_spinlock_init(os_spinlock_t *lock);
+
+/**
+ * Destroy a spinlock, freeing any resources the OS may have allocated.
+ *
+ * Callable from: thread context.
+ *
+ * @param lock pointer to the spinlock to destroy.
+ *
+ * @ingroup spinlock
+ */
+void os_spinlock_destroy(os_spinlock_t *lock);
+
+/**
+ * Lock a spinlock and disable interrupts (after saving the interrupt
+ * state).
+ *
+ * Callable from: any context.
+ *
+ * @param lock pointer to the spinlock to lock.
+ * @param int_state for saved interrupt state.
+ *
+ * @ingroup spinlock
+ */
+void os_spinlock_lock_intsave(os_spinlock_t *lock, os_int_status_t *int_state);
+
+/**
+ * Unlock a spinlock, restoring the prior interrupt state.
+ *
+ * Callable from: any context.
+ *
+ * @param lock spinlock to unlock.
+ * @param int_state interrupt state to restore.
+ *
+ * @ingroup spinlock
+ */
+void os_spinlock_unlock_intrestore(os_spinlock_t *lock, os_int_status_t *int_state);
+
+#endif /* __OSKA_API_DOC */
+
+#ifdef linux
+# include <../linux/spinlock.h>
+#else
+# error <oska/spinlock.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_SPINLOCK_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/thread.h b/unifi_hostsw_linux_147/oska/include/oska/thread.h
new file mode 100644
index 0000000..9ec7d1f
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/thread.h
@@ -0,0 +1,100 @@
+/*
+ * Operating system kernel abstraction -- threading
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_THREAD_H
+#define __OSKA_THREAD_H
+
+#include <oska/semaphore.h>
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup thread Threading
+ *
+ * Threading support depends on the semaphore API provided by
+ * <oska/semaphore.h> (see \ref semaphore).
+ */
+
+/**
+ * Implementation defined thread object.
+ *
+ * @ingroup thread
+ */
+typedef implementation_defined os_thread_t;
+
+/**
+ * Create and start a thread.
+ *
+ * The thread function should call os_thread_should_stop() and return
+ * when it returns true.
+ *
+ * Callable from: thread context.
+ *
+ * @param thread pointer to OS-specific thread data.
+ * @param name thread name.
+ * @param func thread entry-point function.
+ * @param arg argument for func.
+ *
+ * @return 0 on success; negative error code otherwise.
+ *
+ * @ingroup thread
+ */
+int os_thread_create(os_thread_t *thread, const char *name, void (*func)(void *), void *arg);
+
+/**
+ * Stop a thread and wait for it to exit.
+ *
+ * If \a sem is non-NULL it will be posted to awaken the thread. The
+ * thread will also be awakened if it's asleep (in a os_sleep_ms()
+ * call for example).
+ *
+ * Callable from: thread context.
+ *
+ * @param thread the thread to stop.
+ * @param sem a semaphore to post to awaken the thread, may be NULL.
+ *
+ * @return 0 on success; -ve otherwise.
+ *
+ * @ingroup thread
+ */
+void os_thread_stop(os_thread_t *thread, os_semaphore_t *sem);
+
+/**
+ * Return true if the thread should stop (as signalled by a call to
+ * os_thread_stop()).
+ *
+ * @param thread the thread to check.
+ *
+ * @return true iff the thread should stop.
+ *
+ * @ingroup thread
+ */
+int os_thread_should_stop(os_thread_t *thread);
+
+/**
+ * Try to suspend a thread.
+ *
+ * This specifies a point where it is safe for a thread to be
+ * suspended.
+ *
+ * Callable from: thread context.
+ *
+ * @param thread pointer to OS-specific thread data.
+ *
+ * @ingroup thread
+ */
+void os_try_suspend_thread(os_thread_t *thread);
+
+#endif /* __OSKA_API_DOC */
+
+#ifdef linux
+# include <../linux/thread.h>
+#else
+# error <oska/thread.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_THREAD_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/time.h b/unifi_hostsw_linux_147/oska/include/oska/time.h
new file mode 100644
index 0000000..e43707e
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/time.h
@@ -0,0 +1,64 @@
+/*
+ * Operating system kernel abstraction -- timing
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_TIME_H
+#define __OSKA_TIME_H
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup time Timing and delays
+ */
+
+/**
+ * Return the current time (since an arbitrary point) in milliseconds.
+ *
+ * The resolution depends on the OS but would typically be 10 ms or
+ * better.
+ *
+ * Callable from: any context.
+ *
+ * @return current time in ms.
+ *
+ * @ingroup time
+ */
+unsigned long os_current_time_ms(void);
+
+/**
+ * Sleep for a minimum length of time.
+ *
+ * Callable from: thread context.
+ *
+ * @param ms minimum time to sleep (in ms).
+ *
+ * @ingroup time
+ */
+int os_sleep_ms(unsigned ms);
+
+/**
+ * Delay a minimum length of time.
+ *
+ * This may busy-wait and should not be used for long delays (use
+ * os_sleep_ms() instead).
+ *
+ * Callable from: any context.
+ *
+ * @param us minimum time to delay (in us).
+ *
+ * @ingroup time
+ */
+int os_delay_us(unsigned us);
+
+#endif /* __OSKA_API_DOC */
+
+#ifdef linux
+# include <../linux/time.h>
+#else
+# error <oska/time.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_TIME_H */
diff --git a/unifi_hostsw_linux_147/oska/include/oska/util.h b/unifi_hostsw_linux_147/oska/include/oska/util.h
new file mode 100644
index 0000000..15c2ad6
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/include/oska/util.h
@@ -0,0 +1,49 @@
+/*
+ * Operating system kernel abstraction -- misc. utility functions
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_UTIL_H
+#define __OSKA_UTIL_H
+
+#ifdef __OSKA_API_DOC
+/**
+ * @defgroup util Miscellaneous utilties
+ */
+
+/**
+ * Return a CPU (native) byte ordered 16-bit word in little endian
+ * byte order.
+ *
+ * @param x CPU ordered word.
+ *
+ * @return the word in little-endian byte order.
+ *
+ * @ingroup util
+ */
+uint16_t os_cpu_to_le16(uint16_t x);
+
+/**
+ * Return a little endian byte ordered 16-bit word in CPU (native)
+ * byte order.
+ *
+ * @param x little endian word.
+ *
+ * @return the word in native byte order.
+ *
+ * @ingroup util
+ */
+uint16_t os_le16_to_cpu(uint16_t x);
+
+#endif /* __OSKA_API_DOC */
+
+#ifdef linux
+# include <../linux/util.h>
+#else
+# error <oska/util.h> not provided for this OS
+#endif
+
+#endif /* #ifndef __OSKA_UTIL_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/Kbuild b/unifi_hostsw_linux_147/oska/linux/Kbuild
new file mode 100644
index 0000000..2744a6c
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/Kbuild
@@ -0,0 +1,8 @@
+obj-m := oska.o
+
+oska-y := \
+ compat.o \
+ print.o \
+ thread.o
+
+EXTRA_CFLAGS += -I$(M)/../include
diff --git a/unifi_hostsw_linux_147/oska/linux/Makefile b/unifi_hostsw_linux_147/oska/linux/Makefile
new file mode 100644
index 0000000..67307eb
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/Makefile
@@ -0,0 +1,37 @@
+ifeq ($(CONFIG),)
+$(error CONFIG not set)
+endif
+
+all: driver
+
+include config.$(CONFIG).mk
+
+DRIVERTOP := $(shell pwd)/..
+
+# If packaging/ is missing this is a build from released sources, so
+# build in-place.
+ifeq ($(shell test -d $(DRIVERTOP)/packaging && echo y),y)
+BUILDDIR := $(DRIVERTOP)/../builds/$(CONFIG)
+else
+BUILDDIR := $(DRIVERTOP)
+endif
+
+driver: buildtree modules
+
+install: install_driver post_install_hook
+
+install_driver: driver install_modules
+
+clean: clean_modules
+
+buildtree: $(BUILDDIR)
+
+$(BUILDDIR):
+ mkdir -p $(BUILDDIR)
+ find $(BUILDDIR) -type l -exec rm '{}' ';'
+ set -e ; for d in . ; do \
+ mkdir -p $(BUILDDIR)/$$d ; \
+ ( cd $(BUILDDIR)/$$d && $(DRIVERTOP)/scripts/lndir $(DRIVERTOP)/$$d ) ; \
+ done
+
+.PHONY: post_install_hook
diff --git a/unifi_hostsw_linux_147/oska/linux/alloc.h b/unifi_hostsw_linux_147/oska/linux/alloc.h
new file mode 100644
index 0000000..a47007e
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/alloc.h
@@ -0,0 +1,36 @@
+/*
+ * OSKA Linux implementation -- memory allocation
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_ALLOC_H
+#define __OSKA_LINUX_ALLOC_H
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+static inline void *os_alloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
+
+static inline void os_free(void *ptr)
+{
+ kfree(ptr);
+}
+
+static inline void *os_alloc_big(size_t size)
+{
+ return vmalloc(size);
+}
+
+static inline void os_free_big(void *ptr)
+{
+ vfree(ptr);
+}
+
+#endif /* #ifndef __OSKA_LINUX_ALLOC_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/build b/unifi_hostsw_linux_147/oska/linux/build
new file mode 100755
index 0000000..c53edb2
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/build
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+top=$(dirname $0)
+config=$1 ; shift
+config_file=$top/config.$config.mk
+
+if [ "x$config" = "x" ]; then
+ echo "Usage: $0 <config> [<make target/option>]..." >&2
+ exit 1
+fi
+
+if [ ! -e $config_file ]; then
+ echo "Configuration '$config' ($config_file) does not exist." >&2
+ exit 1
+fi
+
+exec make -C ${top} CONFIG=$config "$@"
diff --git a/unifi_hostsw_linux_147/oska/linux/compat.c b/unifi_hostsw_linux_147/oska/linux/compat.c
new file mode 100644
index 0000000..d71968d
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/compat.c
@@ -0,0 +1,54 @@
+/*
+ * Linux version compatibility functions.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/kernel-compat.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+
+int dev_set_name(struct device *dev, const char *fmt, ...)
+{
+ va_list vargs;
+
+ va_start(vargs, fmt);
+ vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
+ va_end(vargs);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dev_set_name);
+
+#endif /* Linux kernel < 2.6.26 */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+
+struct device *class_find_device(struct class *class, struct device *start,
+ void *data, int (*match)(struct device *, void *))
+{
+ struct device *dev;
+
+ list_for_each_entry(dev, &class->devices, node) {
+ if (match(dev, data)) {
+ get_device(dev);
+ return dev;
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(class_find_device);
+
+#endif /* Linux kernel < 2.6.25 */
diff --git a/unifi_hostsw_linux_147/oska/linux/config.arm-linux.mk b/unifi_hostsw_linux_147/oska/linux/config.arm-linux.mk
new file mode 100644
index 0000000..c06818b
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/config.arm-linux.mk
@@ -0,0 +1,8 @@
+ARCH := arm
+CROSS_COMPILE := arm-linux-
+
+ifeq ($(KDIR),)
+$(error Set KDIR to the kernel tree to build against)
+endif
+
+include config.generic.mk
diff --git a/unifi_hostsw_linux_147/oska/linux/config.generic.mk b/unifi_hostsw_linux_147/oska/linux/config.generic.mk
new file mode 100644
index 0000000..b3696d7
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/config.generic.mk
@@ -0,0 +1,24 @@
+KDIR ?= /lib/modules/$(shell uname -r)/build
+prefix ?= /usr/local
+
+modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR)/linux \
+ O=$(O) V=$(V)
+
+install_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR)/linux modules_install INSTALL_MOD_PATH=$(DESTDIR) \
+ O=$(O) V=$(V)
+
+clean_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR)/linux clean \
+ O=$(O) V=$(V)
+
+ifneq ($(CROSS_COMPILE),)
+export CROSS_COMPILE
+endif
+
+ifneq ($(ARCH),)
+export ARCH
+endif
+
+export prefix
diff --git a/unifi_hostsw_linux_147/oska/linux/mutex.h b/unifi_hostsw_linux_147/oska/linux/mutex.h
new file mode 100644
index 0000000..ff94628
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/mutex.h
@@ -0,0 +1,35 @@
+/*
+ * OSKA Linux implementation -- mutexes
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_MUTEX_H
+#define __OSKA_LINUX_MUTEX_H
+
+#include <linux/kernel.h>
+
+#include <linux/kernel-compat.h>
+
+/* Real mutexes were only added to 2.6.16 so use semaphores
+ instead. */
+typedef struct semaphore os_mutex_t;
+
+static inline void os_mutex_init(os_mutex_t *mutex)
+{
+ init_MUTEX(mutex);
+}
+
+static inline void os_mutex_lock(os_mutex_t *mutex)
+{
+ down(mutex);
+}
+
+static inline void os_mutex_unlock(os_mutex_t *mutex)
+{
+ up(mutex);
+}
+
+#endif /* __OSKA_LINUX_MUTEX_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/print.c b/unifi_hostsw_linux_147/oska/linux/print.c
new file mode 100644
index 0000000..af6fd57
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/print.c
@@ -0,0 +1,48 @@
+/*
+ * Linux console printing functions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+
+#include <oska/print.h>
+
+void os_print(enum os_print_level level, const char *prefix, const char *name,
+ const char *format, ...)
+{
+ va_list va_args;
+
+ va_start(va_args, format);
+ os_vprint(level, prefix, name, format, va_args);
+ va_end(va_args);
+}
+EXPORT_SYMBOL(os_print);
+
+void os_vprint(enum os_print_level level, const char *prefix, const char *name,
+ const char *format, va_list args)
+{
+ const char *level_str[] = {
+ [OS_PRINT_ERROR] = KERN_ERR,
+ [OS_PRINT_WARNING] = KERN_WARNING,
+ [OS_PRINT_INFO] = KERN_INFO,
+ [OS_PRINT_DEBUG] = KERN_DEBUG,
+ };
+ char buf[80];
+ int w = 0;
+
+ if (name) {
+ w += snprintf(buf + w, sizeof(buf) - w, "%s%s%s: ", level_str[level], prefix, name);
+ } else {
+ w += snprintf(buf + w, sizeof(buf) - w, "%s%s", level_str[level], prefix);
+ }
+ w += vsnprintf(buf + w, sizeof(buf) - w, format, args);
+ printk("%s\n", buf);
+}
+EXPORT_SYMBOL(os_vprint);
+
+MODULE_DESCRIPTION("Operating System Kernel Abstraction");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/oska/linux/print.h b/unifi_hostsw_linux_147/oska/linux/print.h
new file mode 100644
index 0000000..a2cad48
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/print.h
@@ -0,0 +1,19 @@
+/*
+ * OSKA Linux implementation -- console printing
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_PRINT_H
+#define __OSKA_LINUX_PRINT_H
+
+#include <linux/kernel.h>
+
+void os_print(enum os_print_level level, const char *prefix, const char *name,
+ const char *format, ...);
+void os_vprint(enum os_print_level level, const char *prefix, const char *name,
+ const char *format, va_list args);
+
+#endif /* #ifndef __OSKA_LINUX_PRINT_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/semaphore.h b/unifi_hostsw_linux_147/oska/linux/semaphore.h
new file mode 100644
index 0000000..cf52e0d
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/semaphore.h
@@ -0,0 +1,33 @@
+/*
+ * OSKA Linux implementation -- semaphores
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_SEMAPHORE_H
+#define __OSKA_LINUX_SEMAPHORE_H
+
+#include <linux/kernel.h>
+
+#include <linux/kernel-compat.h>
+
+typedef struct semaphore os_semaphore_t;
+
+static inline void os_semaphore_init(os_semaphore_t *sem)
+{
+ sema_init(sem, 0);
+}
+
+static inline void os_semaphore_wait(os_semaphore_t *sem)
+{
+ down(sem);
+}
+
+static inline void os_semaphore_post(os_semaphore_t *sem)
+{
+ up(sem);
+}
+
+#endif /* __OSKA_LINUX_SEMAPHORE_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/spinlock.h b/unifi_hostsw_linux_147/oska/linux/spinlock.h
new file mode 100644
index 0000000..157b350
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/spinlock.h
@@ -0,0 +1,43 @@
+/*
+ * OSKA Linux implementation -- spinlocks
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_SPINLOCK_H
+#define __OSKA_LINUX_SPINLOCK_H
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+typedef spinlock_t os_spinlock_t;
+typedef unsigned long os_int_status_t;
+
+static inline void os_spinlock_init(os_spinlock_t *lock)
+{
+ spinlock_t *l = (spinlock_t *)lock;
+ spin_lock_init(l);
+}
+
+static inline void os_spinlock_destroy(os_spinlock_t *lock)
+{
+ /* no op */
+}
+
+static inline void os_spinlock_lock_intsave(os_spinlock_t *lock,
+ os_int_status_t *int_state)
+{
+ spinlock_t *l = (spinlock_t *)lock;
+ spin_lock_irqsave(l, *int_state);
+}
+
+static inline void os_spinlock_unlock_intrestore(os_spinlock_t *lock,
+ os_int_status_t *int_state)
+{
+ spinlock_t *l = (spinlock_t *)lock;
+ spin_unlock_irqrestore(l, *int_state);
+}
+
+#endif /* #ifndef __OSKA_LINUX_SPINLOCK_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/thread.c b/unifi_hostsw_linux_147/oska/linux/thread.c
new file mode 100644
index 0000000..d82ca6a
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/thread.c
@@ -0,0 +1,66 @@
+/*
+ * Linux thread functions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+
+#include <oska/thread.h>
+
+static int thread_func(void *data)
+{
+ os_thread_t *thread = data;
+
+ thread->func(thread->arg);
+
+ /*
+ * kthread_stop() cannot handle the thread exiting while
+ * kthread_should_stop() is false, so sleep until kthread_stop()
+ * wakes us up.
+ */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!kthread_should_stop())
+ schedule();
+
+ return 0;
+}
+
+int os_thread_create(os_thread_t *thread, const char *name, void (*func)(void *), void *arg)
+{
+ thread->func = func;
+ thread->arg = arg;
+
+ thread->stop = 0;
+
+ thread->task = kthread_run(thread_func, thread, name);
+ if (IS_ERR(thread->task)) {
+ return PTR_ERR(thread->task);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(os_thread_create);
+
+void os_thread_stop(os_thread_t *thread, os_semaphore_t *sem)
+{
+ /*
+ * Stop flag must be set before the semaphore is posted so
+ * kthread_should_stop() cannot be used.
+ */
+ thread->stop = 1;
+
+ if (sem) {
+ os_semaphore_post(sem);
+ }
+
+ kthread_stop(thread->task);
+}
+EXPORT_SYMBOL(os_thread_stop);
+
+int os_thread_should_stop(os_thread_t *thread)
+{
+ return thread->stop;
+}
+EXPORT_SYMBOL(os_thread_should_stop);
diff --git a/unifi_hostsw_linux_147/oska/linux/thread.h b/unifi_hostsw_linux_147/oska/linux/thread.h
new file mode 100644
index 0000000..eb29630
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/thread.h
@@ -0,0 +1,38 @@
+/*
+ * OSKA Linux implementation -- threading
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_THREAD_H
+#define __OSKA_LINUX_THREAD_H
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
+#include <linux/freezer.h>
+#endif
+
+struct os_thread_lx {
+ void (*func)(void *);
+ void *arg;
+ struct task_struct *task;
+ int stop;
+};
+
+typedef struct os_thread_lx os_thread_t;
+
+int os_thread_create(os_thread_t *thread, const char *name,
+ void (*func)(void *), void *arg);
+void os_thread_stop(os_thread_t *thread, os_semaphore_t *sem);
+int os_thread_should_stop(os_thread_t *thread);
+
+static inline void os_try_suspend_thread(os_thread_t *thread)
+{
+ try_to_freeze();
+}
+
+#endif /* __OSKA_LINUX_THREAD_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/time.h b/unifi_hostsw_linux_147/oska/linux/time.h
new file mode 100644
index 0000000..38a721a
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/time.h
@@ -0,0 +1,32 @@
+/*
+ * OSKA Linux implementation -- timing
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_TIME_H
+#define __OSKA_LINUX_TIME_H
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+
+static inline unsigned long os_current_time_ms(void)
+{
+ return jiffies_to_msecs(jiffies);
+}
+
+static inline void os_sleep_ms(unsigned ms)
+{
+ msleep_interruptible(ms);
+}
+
+static inline void os_delay_us(unsigned us)
+{
+ udelay(us);
+}
+
+#endif /* __OSKA_LINUX_TIME_H */
diff --git a/unifi_hostsw_linux_147/oska/linux/util.h b/unifi_hostsw_linux_147/oska/linux/util.h
new file mode 100644
index 0000000..54ccf6a
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/linux/util.h
@@ -0,0 +1,25 @@
+/*
+ * OSKA Linux implementation -- misc. utility functions
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef __OSKA_LINUX_UTILS_H
+#define __OSKA_LINUX_UTILS_H
+
+#include <linux/kernel.h>
+#include <asm/byteorder.h>
+
+static inline uint16_t os_le16_to_cpu(uint16_t x)
+{
+ return le16_to_cpu(x);
+}
+
+static inline uint16_t os_cpu_to_le16(uint16_t x)
+{
+ return cpu_to_le16(x);
+}
+
+#endif /* __OSKA_LINUX_UTILS_H */
diff --git a/unifi_hostsw_linux_147/oska/scripts/lndir b/unifi_hostsw_linux_147/oska/scripts/lndir
new file mode 100755
index 0000000..a746156
--- /dev/null
+++ b/unifi_hostsw_linux_147/oska/scripts/lndir
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+
+canon() {
+ DIR=`dirname $1`
+ BASE=`basename $1`
+ CURDIR=`pwd`
+ cd $DIR
+ CANONDIR=`pwd`
+ cd $CURDIR
+ echo "$CANONDIR/$BASE"
+}
+
+lndir() {
+ FIND=`echo $1 | sed -e 's,/\\+,/,g'`
+ for d in `find $FIND -type d`; do
+ MODE=`stat -c %a $d`
+ NEW=`echo $d | sed -e "s,$FIND/*,,"`
+ test -n "$NEW" && mkdir -m $MODE $NEW
+ done
+ for f in `find $FIND -type f`; do
+ NEW=`echo $f | sed -e "s,$FIND/*,,"`
+ if test -n "$NEW"; then
+ OLD=`canon $f`
+ ln -s $OLD $NEW
+ fi
+ done
+}
+
+
+usage() {
+ echo "lndir <dir>"
+ echo "This is a sort-of-replacement for lndir using the shell and"
+ echo "standard shell commands. It makes a symlinked copy of the given"
+}
+
+test -z "$1" && usage && exit 1
+test -n "$2" && usage && exit 1
+lndir $1
diff --git a/unifi_hostsw_linux_147/sdioemb/.buildid b/unifi_hostsw_linux_147/sdioemb/.buildid
new file mode 100644
index 0000000..60d3b2f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/.buildid
@@ -0,0 +1 @@
+15
diff --git a/unifi_hostsw_linux_147/sdioemb/Doxyfile b/unifi_hostsw_linux_147/sdioemb/Doxyfile
new file mode 100644
index 0000000..5674d0f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/Doxyfile
@@ -0,0 +1,1237 @@
+# Doxyfile 1.4.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = sdioemb
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = .
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 1
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/unifi_hostsw_linux_147/sdioemb/Kbuild b/unifi_hostsw_linux_147/sdioemb/Kbuild
new file mode 100644
index 0000000..561d07a
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/Kbuild
@@ -0,0 +1,92 @@
+obj-m := sdio.o sdio_uif.o cards/
+
+ifeq ($(CONFIG_PCI),y)
+obj-m += slot_shc.o
+endif
+
+ifdef CONFIG_USB
+obj-m += slot_ushc.o
+endif
+
+ifeq ($(CONFIG_PXA27x),y)
+obj-m += slot_pxa27x.o
+endif
+
+ifeq ($(CONFIG_MACH_ARCOM_ZEUS),y)
+obj-m += slot_zeus.o
+endif
+
+ifeq ($(CONFIG_PXA_SHARP_Cxx00),y)
+obj-m += slot_sharp_cxx00.o
+endif
+
+ifeq ($(CONFIG_ARCH_MX27),y)
+obj-m += slot_imx27.o
+endif
+
+ifeq ($(CONFIG_MACH_MX27ADS),y)
+obj-m += slot_imx27ads.o
+endif
+
+ifeq ($(CONFIG_ARCH_MX3),y)
+obj-m += slot_imx31.o
+endif
+
+ifeq ($(CONFIG_MACH_MX31ADS),y)
+obj-m += slot_imx31ads.o
+endif
+
+
+ifeq ($(CONFIG_SPI),y)
+obj-m += slot_spi.o
+endif
+
+sdio-y := \
+ sdio_card.o \
+ sdio_cis.o \
+ sdio_cmd.o \
+ sdio_core.o \
+ sdio_cspi.o \
+ sdio_func.o \
+ sdio_int.o \
+ sdio_pm.o \
+ sdio_io.o \
+ sdio_slot.o \
+ sdio_event_log.o
+
+sdio-y += \
+ sdio_lx.o \
+ sdio_os_event_log_lx.o \
+
+sdio_uif-y := \
+ fdrv_uif_lx.o
+
+slot_shc-y := \
+ slot_shc_pci_lx.o
+
+slot_ushc-y := \
+ slot_ushc_lx.o
+
+slot_pxa27x-y := \
+ slot_pxa27x_lx.o
+
+slot_zeus-y := \
+ slot_zeus_lx.o
+
+slot_imx27-y := \
+ slot_imx27_lx.o
+
+slot_imx27ads-y := \
+ slot_imx27ads_lx.o
+
+slot_imx31-y := \
+ slot_imx31_lx.o
+
+slot_imx31ads-y := \
+ slot_imx31ads_lx.o
+
+slot_spi-y := \
+ slot_spi_lx.o
+
+EXTRA_CFLAGS += -I$(M) -I$(M)/include -I$(OSKADIR)/include \
+ $(EXTRA_DRV_CFLAGS)
diff --git a/unifi_hostsw_linux_147/sdioemb/LICENSE.txt b/unifi_hostsw_linux_147/sdioemb/LICENSE.txt
new file mode 100644
index 0000000..ca19f80
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/LICENSE.txt
@@ -0,0 +1,39 @@
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+Except as contained in this notice, the names of above-listed
+copyright holders and the names of any contributors shall not be used
+in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 (or later) as published
+by the Free Software Foundation.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from this file, or you compile this file
+and link it with other works to produce a work based on this file,
+this file does not by itself cause the resulting work to be covered by
+the GNU General Public License. However the source code for this file
+must still be made available in accordance with section (3) of the GNU
+General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
diff --git a/unifi_hostsw_linux_147/sdioemb/Makefile b/unifi_hostsw_linux_147/sdioemb/Makefile
new file mode 100644
index 0000000..69cc755
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/Makefile
@@ -0,0 +1,68 @@
+ifeq ($(CONFIG),)
+$(error CONFIG not set)
+endif
+
+all: driver libsdio tools
+
+include config.$(CONFIG).mk
+
+DRIVERTOP := $(shell pwd)
+
+ifeq ($(OSKADIR),)
+OSKADIR := $(DRIVERTOP)/../../oska/main
+export OSKADIR
+endif
+
+# If packaging/ is missing this is a build from released sources, so
+# build in-place.
+ifeq ($(shell test -d $(DRIVERTOP)/packaging && echo y),y)
+BUILDDIR := $(DRIVERTOP)/../builds/$(CONFIG)
+else
+BUILDDIR := $(DRIVERTOP)
+endif
+
+driver: buildtree version modules
+
+libsdio: buildtree
+ $(MAKE) -C $(BUILDDIR)/libsdio
+
+tools: buildtree
+ $(MAKE) -C $(BUILDDIR)/tools
+
+install: install_driver install_libsdio install_tools post_install_hook
+
+install_libsdio: libsdio
+ $(MAKE) -C $(BUILDDIR)/libsdio install
+
+install_driver: driver install_modules
+
+install_tools: tools
+ $(MAKE) -C $(BUILDDIR)/tools install
+
+clean: clean_modules clean_tools
+
+clean_tools:
+ $(MAKE) -C $(BUILDDIR)/tools clean
+
+buildtree: $(BUILDDIR)
+
+$(BUILDDIR):
+ mkdir -p $(BUILDDIR)
+ find $(BUILDDIR) -type l -exec rm '{}' ';'
+ set -e ; for d in . ; do \
+ mkdir -p $(BUILDDIR)/$$d ; \
+ ( cd $(BUILDDIR)/$$d && $(DRIVERTOP)/scripts/lndir $(DRIVERTOP)/$$d ) ; \
+ done
+
+VERSION_H := $(BUILDDIR)/sdio_version.h
+
+version:
+ echo "#define SDD_BUILD_DATE \"$$(date +'%d %b %Y %H:%M:%S')\"" > $(VERSION_H)
+ echo "#define SDD_BUILDID $$(cat .buildid)" >> $(VERSION_H)
+ if [ -d packaging ]; then \
+ echo "#define SDD_BUILDID_EXTRA \"*\"" >> $(VERSION_H) ; \
+ else \
+ echo "#define SDD_BUILDID_EXTRA \"\"" >> $(VERSION_H) ; \
+ fi
+
+.PHONY: post_install_hook
diff --git a/unifi_hostsw_linux_147/sdioemb/README b/unifi_hostsw_linux_147/sdioemb/README
new file mode 100644
index 0000000..df8ecd5
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/README
@@ -0,0 +1,57 @@
+Generating the API documention
+------------------------------
+
+1. Generate the API documentation using the doxygen tool.
+
+ $ doxygen
+
+ The documentation will be generated as HTML in the html/ directory.
+
+Building and installing on Linux
+--------------------------------
+
+1. Build and install the Operating System Kernel Abstraction (oska)
+ module. Refer to the oska documentation for details.
+
+2. Build the driver and tools using the 'generic' configuration.
+
+ $ ./build generic OSKADIR=<path to oska sources>
+
+ The default for OSKADIR is ../../oska/main.
+
+3. Install the driver and tools.
+
+ $ sudo ./build generic install
+
+ By default, the tools are installed in /usr/local.
+
+Available configurations:
+
+generic Host running Linux kernel 2.6.x
+debug Generic with debugging enabled
+arm-linux arm-linux target running 2.6.x (must specify KDIR)
+
+These configurations are specified in makefile fragments named
+config.<config>.mk.
+
+Useful variables include:
+
+ Variable Description Default
+ KDIR path to kernel source tree /lib/modules/`uname -r`/build
+ ARCH kernel architecture (e.g., ARM) unset
+ CROSS_COMPILE cross compiler prefix (e.g., arm-linux-) unset
+ O Kbuild's O (output directory) option unset
+ V Kbuild's V (verbosity) option unset
+ prefix Installation tree prefix /usr/local
+
+Additional configurations can be created to set any required variables
+before including the appropriate generic configuration. For example,
+for an arm-linux build (with the kernel in ~/work/linux-2.6.16.28):
+
+ KDIR := $(HOME)/work/linux-2.6.16.28
+
+ include config.arm-linux.mk
+
+Variables can also be specified on the command line.
+
+ $ ./build generic V=1
diff --git a/unifi_hostsw_linux_147/sdioemb/README-BETA-RELEASE b/unifi_hostsw_linux_147/sdioemb/README-BETA-RELEASE
new file mode 100644
index 0000000..b809c30
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/README-BETA-RELEASE
@@ -0,0 +1,10 @@
+Use of beta release software is at your own risk. This software is
+provided "as is," and CSR cautions users to determine for themselves
+the suitability of using the beta version of this software. CSR makes
+no warranty or representation whatsoever of merchantability or
+fitness of the product for any particular purpose or use. In no event
+shall CSR be liable for any consequential, incidental or special
+damages whatsoever arising out of the use of or inability to use this
+software, even if the user has advised CSR of the possibility of such
+damages. This software is for you alone, and is not to be
+redistributed.
diff --git a/unifi_hostsw_linux_147/sdioemb/build b/unifi_hostsw_linux_147/sdioemb/build
new file mode 100755
index 0000000..c53edb2
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/build
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+top=$(dirname $0)
+config=$1 ; shift
+config_file=$top/config.$config.mk
+
+if [ "x$config" = "x" ]; then
+ echo "Usage: $0 <config> [<make target/option>]..." >&2
+ exit 1
+fi
+
+if [ ! -e $config_file ]; then
+ echo "Configuration '$config' ($config_file) does not exist." >&2
+ exit 1
+fi
+
+exec make -C ${top} CONFIG=$config "$@"
diff --git a/unifi_hostsw_linux_147/sdioemb/cards/Kbuild b/unifi_hostsw_linux_147/sdioemb/cards/Kbuild
new file mode 100644
index 0000000..e277e05
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/cards/Kbuild
@@ -0,0 +1,6 @@
+obj-m := sdio_lib_bt_a.o
+
+sdio_lib_bt_a-y := lib_bt_a.o lib_bt_a_lx.o
+
+EXTRA_CFLAGS += -I$(M) -I$(M)/include -I$(OSKADIR)/include \
+ $(EXTRA_DRV_CFLAGS)
diff --git a/unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a.c b/unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a.c
new file mode 100644
index 0000000..6b9e950
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a.c
@@ -0,0 +1,440 @@
+/*
+ * Core BT Type-A operations.
+ *
+ * Copyright (C) 2006-2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <oska/all.h>
+
+#include <sdioemb/sdio.h>
+#include <sdioemb/sdio_api.h>
+#include <sdioemb/sdio_cis.h>
+#include <sdioemb/sdio_bt_a.h>
+
+#define BC_FIRMWARE_START_TIMEOUT_MS 100
+#define SDIO_CSR_TO_HOST_SCRATCH0_INITED 0x1
+
+static void bt_warn(struct sdio_bt_a_dev *bt, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ os_vprint(OS_PRINT_WARNING, "", bt->name, format, args);
+ va_end(args);
+}
+
+static void bt_err(struct sdio_bt_a_dev *bt, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ os_vprint(OS_PRINT_ERROR, "", bt->name, format, args);
+ va_end(args);
+}
+
+/**
+ * Read CIS to determine if read acknowledges are required.
+ *
+ * @param bt the BT device.
+ *
+ * @return true if read acknowledges are required; false otherwise.
+ */
+static int needs_read_ack(struct sdio_bt_a_dev *bt)
+{
+ uint8_t tpl[3];
+ int err;
+
+ err = sdio_cis_get_tuple(bt->fdev, CISTPL_SDIO_STD, tpl, sizeof(tpl));
+ if (err) {
+ /* If the tuple doesn't exist and this is a CSR chip, then
+ read acks are not required. */
+ if (err == -ENXIO && bt->fdev->vendor_id == SDIO_MANF_ID_CSR) {
+ return 0;
+ }
+ return 1;
+ }
+
+ return tpl[2] == 0x00;
+}
+
+/**
+ * Disable read acknowledges if supported by the hardware.
+ *
+ * @param bt the BT device.
+ */
+static void disable_read_acks(struct sdio_bt_a_dev *bt)
+{
+ int err;
+
+ if (bt->needs_read_ack) {
+ return;
+ }
+
+ err = sdio_write8(bt->fdev, SDIO_BT_A_RETRY_CTRL, RTC_SET);
+ if (err) {
+ bt_warn(bt, "could not disable read acks (%d)", err);
+ bt->needs_read_ack = 1;
+ }
+}
+
+/**
+ * Start a BT Type-A function.
+ *
+ * The function is enabled, read acknowledges are disabled (if
+ * supported by the hardware) and finally interrupts are enabled.
+ *
+ * The sleep state is also set to AWAKE to ensure the software and
+ * hardware deep sleep states are in sync.
+ *
+ * @param bt the BT device.
+ */
+void sdio_bt_a_start(struct sdio_bt_a_dev *bt)
+{
+ int timeout_ms = BC_FIRMWARE_START_TIMEOUT_MS;
+
+ sdio_bt_a_set_sleep_state(bt, SLEEP_STATE_AWAKE);
+ sdio_enable_function(bt->fdev);
+
+ /*
+ * For some hardware the I/O Ready bit is set before the device is
+ * ready. In this case we wait for firmware to start by polling
+ * bit 0 in TO_HOST_SCRATCH0.
+ */
+ if (bt->wait_for_firmware) {
+ while (--timeout_ms) {
+ uint8_t scratch0;
+ sdio_f0_read8(bt->fdev, SDIO_CSR_TO_HOST_SCRATCH0, &scratch0);
+ if (scratch0 == SDIO_CSR_TO_HOST_SCRATCH0_INITED) {
+ break;
+ }
+ os_sleep_ms(1);
+ }
+ if (timeout_ms == 0) {
+ bt_warn(bt, "timed out waiting for firmware to start");
+ }
+ }
+
+ disable_read_acks(bt);
+ sdio_write8(bt->fdev, SDIO_BT_A_INT_EN, EN_INTRD);
+}
+
+/**
+ * Stop a BT Type-A function.
+ *
+ * The function is disabled.
+ *
+ * @param bt the BT device.
+ */
+void sdio_bt_a_stop(struct sdio_bt_a_dev *bt)
+{
+ sdio_disable_function(bt->fdev);
+}
+
+/**
+ * Restart the function if a hardware reset occurred.
+ *
+ * If the hardware is reset by an internal watchdog (or similar), the
+ * function must be reenabled prior to attempting any SDIO commands to
+ * it.
+ *
+ * A watchdog reset is identified by the I/O Enable bit being set and
+ * the Extended I/O Enable bit being clear. In all uses of the
+ * function we expect I/O Enable to be set so on the Extended I/O
+ * Enable bit is checked.
+ *
+ * @param bt the BT device.
+ *
+ * @return 1 if a reset had occurred; 0 if a reset had not occurred;
+ * -ve on error (-ENODEV, -EIO etc).
+ */
+int sdio_bt_a_check_for_reset(struct sdio_bt_a_dev *bt)
+{
+ uint8_t ext_io_en;
+ int ret;
+
+ ret = sdio_f0_read8(bt->fdev, SDIO_CSR_EXT_IO_EN, &ext_io_en);
+ if (ret == 0 && !(ext_io_en & (1 << bt->fdev->function))) {
+ bt_warn(bt, "watchdog reset detected");
+ sdio_bt_a_start(bt);
+ return 1;
+ }
+ return ret;
+}
+
+/**
+ * Write a packet to the hardware.
+ *
+ * The entire packet is written in a single SDIO command.
+ *
+ * I/O errors cause the packet write to be retries, fatal errors (too
+ * many retries) will be reported to the caller.
+ *
+ * @param bt the BT device.
+ * @param packet packet to write including the Type-A header.
+ * @param len total length of the packet.
+ *
+ * @return 0 on success; -ve on error.
+ */
+int sdio_bt_a_send(struct sdio_bt_a_dev *bt, const struct sdio_bt_a_pkt_info *pkt)
+{
+ int ret = 0;
+ int retry;
+
+ for (retry = 0; retry < bt->max_tx_retries; retry++) {
+ ret = sdio_write(bt->fdev, SDIO_BT_A_TD, pkt->hdr, pkt->data_len + SDIO_BT_A_HEADER_LEN);
+ if (ret == 0)
+ break;
+
+ bt_warn(bt, "write packet failed (%d), retrying", ret);
+ sdio_write8(bt->fdev, SDIO_BT_A_TX_PKT_CTRL, PC_WRT);
+ }
+
+ if (retry >= bt->max_tx_retries) {
+ bt_err(bt, "maximum number of write retries exceeded");
+ sdio_bt_a_check_for_reset(bt);
+ }
+
+ return ret;
+}
+
+/**
+ * Read a packet from the hardware.
+ *
+ * The 4 octet Type-A transport header and part of the payload data is
+ * read. The header is used to determine the total length of the
+ * packet and the remaining data (if any) is read (using a read padded
+ * to a whole number of blocks).
+ *
+ * If an I/O error occurs the packet read is retried. Fatal errors
+ * (no memory, too many retries) cause the packet to be silently
+ * discarded.
+ *
+ * The read packet ready interrupt is cleared prior to reading (or
+ * re-reading) a packet so the hardware will make the packet data
+ * available.
+ *
+ * @param bt the BT device.
+ * @param pkt read packet information.
+ *
+ * @return 0 on success; -ve on error.
+ */
+static int rx_packet(struct sdio_bt_a_dev *bt, struct sdio_bt_a_pkt_info *pkt)
+{
+ int ret = 0;
+ int retry = 0;
+ int remaining_len = 0;
+
+ pkt->data_len = 0;
+ pkt->data = os_alloc(SDIO_BT_A_HEADER_LEN + SDIO_BT_A_MIN_READ);
+ if (pkt->data == NULL) {
+ bt_err(bt, "no memory for Rx packet");
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ do {
+ sdio_write8(bt->fdev, SDIO_BT_A_INTRD, CL_INTRD);
+
+ /* Read header and part of the packet data. */
+ ret = sdio_read(bt->fdev, SDIO_BT_A_RD, pkt->data,
+ SDIO_BT_A_HEADER_LEN + SDIO_BT_A_MIN_READ);
+ if (ret < 0) {
+ goto retry_read;
+ }
+
+ if (pkt->data_len == 0) {
+ memcpy(pkt->hdr, pkt->data, SDIO_BT_A_HEADER_LEN);
+
+ pkt->data_len = sdio_bt_a_packet_len(pkt->hdr) - SDIO_BT_A_HEADER_LEN;
+
+ if (pkt->data_len <= 0 || pkt->data_len > SDIO_BT_A_PACKET_LEN_MAX) {
+ bt_err(bt, "bad rx packet length (%d)", pkt->data_len);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (pkt->data_len > SDIO_BT_A_MIN_READ) {
+ remaining_len = pkt->data_len - SDIO_BT_A_MIN_READ;
+ if (remaining_len > bt->fdev->blocksize) {
+ remaining_len = (remaining_len + bt->fdev->blocksize - 1)
+ / bt->fdev->blocksize * bt->fdev->blocksize;
+ }
+ }
+
+ /* Allocate more memory if required and move the packet
+ data to the start of the buffer */
+ if (remaining_len + SDIO_BT_A_MIN_READ > SDIO_BT_A_MIN_READ) {
+ int buf_size;
+ void *new_data;
+
+ buf_size = SDIO_BT_A_MIN_READ + remaining_len;
+
+ new_data = os_alloc(buf_size);
+ if (new_data == NULL) {
+ bt_err(bt, "no memory for Rx packet");
+ ret = -ENOMEM;
+ goto done;
+ }
+ memcpy(new_data, pkt->data + SDIO_BT_A_HEADER_LEN, SDIO_BT_A_MIN_READ);
+ os_free(pkt->data);
+ pkt->data = new_data;
+ } else {
+ memmove(pkt->data, pkt->data + SDIO_BT_A_HEADER_LEN, pkt->data_len);
+ }
+ }
+
+ /* Read any remaining data. */
+ if (remaining_len) {
+ ret = sdio_read(bt->fdev, SDIO_BT_A_RD,
+ pkt->data + SDIO_BT_A_MIN_READ, remaining_len);
+ }
+ if (ret == 0)
+ goto done;
+
+ retry_read:
+ sdio_write8(bt->fdev, SDIO_BT_A_RX_PKT_CTRL, PC_RRT);
+ } while (++retry < bt->max_rx_retries);
+
+ done:
+ if (ret != -ENODEV) {
+ /* Acknowledge read if the hardware requires it, or if an error
+ occured (so the hardware discards the packet). */
+ if (bt->needs_read_ack || ret < 0) {
+ sdio_write8(bt->fdev, SDIO_BT_A_RX_PKT_CTRL, 0x00);
+ }
+ if (retry >= bt->max_rx_retries && ret != -ENODEV) {
+ bt_err(bt, "maximum number of read retries exceeded");
+ sdio_bt_a_check_for_reset(bt);
+ }
+ }
+ if (ret < 0)
+ os_free(pkt->data);
+ return ret;
+}
+
+/**
+ * Set the deep sleep state.
+ *
+ * The deep sleep state management is necessary as SDIO commands to
+ * the BT Type-A function fail when the hardware is in deep sleep,
+ * thus prior to reading or writing packets we must ensure the chip is
+ * awake.
+ *
+ * The following state transitions are handled.
+ *
+ * AWAKE -> TORPID: In response to an idle timer expiring (or
+ * similar), simply write TORPID to the state register to permit the
+ * chip to enter deep sleep.
+ *
+ * TORPID -> DROWSY: In response to the host software wishing to write
+ * a packet, set the state to DROWSY and wait for the state to be
+ * AWAKE.
+ *
+ * DROWSY/TORPID -> AWAKE: An interrupt indicates that the chip is
+ * awake, set the state to AWAKE and wake up any threads waiting for
+ * AWAKE.
+ *
+ * @param bt the BT device.
+ * @param state state to transition to.
+ */
+void sdio_bt_a_set_sleep_state(struct sdio_bt_a_dev *bt, enum sdio_sleep_state state)
+{
+ int r;
+
+ if (state == bt->sleep_state) {
+ return;
+ }
+
+ /*
+ * The awake interrupt is sourced from the 'core clock running'
+ * signal, this is deasserted 1 slow clock (1 kHz) cycle after the
+ * core clock is stopped. If the DROWSY state is set within 1 ms
+ * of the core clock being stopped then a spurious wake up
+ * interrupt occurs.
+ *
+ * Setting AWAKE and then waiting 1 ms before setting DROWSY
+ * ensures we don't set DROWSY during this unsafe window.
+ */
+ if (state == SLEEP_STATE_DROWSY) {
+ sdio_f0_write8(bt->fdev, SDIO_CSR_SLEEP_STATE,
+ SDIO_CSR_SLEEP_STATE_FUNC(bt->fdev->function) | SLEEP_STATE_AWAKE);
+ os_sleep_ms(1);
+ }
+
+ r = sdio_f0_write8(bt->fdev, SDIO_CSR_SLEEP_STATE,
+ SDIO_CSR_SLEEP_STATE_FUNC(bt->fdev->function) | state);
+ if (r != 0) {
+ return;
+ }
+ bt->sleep_state = state;
+
+ bt->sleep_state_changed(bt);
+}
+
+/**
+ * Handle an interrupt from the function.
+ *
+ * The chip will only raise an interrupts if it is awake and will not
+ * enter deep sleep while an interrupt is asserted, so we first set
+ * the sleep state to AWAKE.
+ *
+ * The sources of interrupt is then identified and handled. The three
+ * possible sources are:
+ *
+ * 1. Read packet ready. The packet is read from the hardware and
+ * added to the received packet queue.
+ *
+ * 2. Awake. This may only occur when the sleep state is DROWSY and
+ * no action other than setting the sleep state is required.
+ *
+ * 3. Generic interrupt. The hardware provides a facility for the
+ * firmware to raise an interrupt (via the SDIO_HOST_INT
+ * register). The current firmware makes no use of this so we
+ * just clear the interrupt.
+ *
+ * @param bt the BT device.
+ */
+void sdio_bt_a_handle_interrupt(struct sdio_bt_a_dev *bt)
+{
+ uint8_t rdint;
+ int err;
+ int wake_up_expected;
+ struct sdio_bt_a_pkt_info pkt;
+
+ wake_up_expected = bt->sleep_state == SLEEP_STATE_DROWSY;
+ sdio_bt_a_set_sleep_state(bt, SLEEP_STATE_AWAKE);
+
+ /* If a wake up isn't expected, the only interrupt source is
+ 'packet read ready' so skip reading the INTRD register. */
+ if (wake_up_expected) {
+ err = sdio_read8(bt->fdev, SDIO_BT_A_INTRD, &rdint);
+ if (err) {
+ if (err != -ENODEV && sdio_bt_a_check_for_reset(bt) == 1) {
+ err = sdio_read8(bt->fdev, SDIO_BT_A_INTRD, &rdint);
+ }
+ if (err) {
+ return;
+ }
+ }
+ if (!(rdint & INTRD)) {
+ return;
+ }
+ }
+
+ err = rx_packet(bt, &pkt);
+ if (!err) {
+ bt->receive(bt, &pkt);
+ }
+}
+
+void sdio_bt_a_init(struct sdio_bt_a_dev *bt, struct sdio_dev *fdev)
+{
+ bt->fdev = fdev;
+ bt->max_tx_retries = 3;
+ bt->max_rx_retries = 3;
+ bt->needs_read_ack = needs_read_ack(bt);
+ bt->wait_for_firmware = 0;
+ bt->sleep_state = SLEEP_STATE_TORPID; /* safe state to assume */
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a_lx.c b/unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a_lx.c
new file mode 100644
index 0000000..b2fa6c6
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/cards/lib_bt_a_lx.c
@@ -0,0 +1,18 @@
+/*
+ * Core BT Type-A operations.
+ *
+ * Copyright (C) 2006-2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+
+#include <sdioemb/sdio_bt_a.h>
+
+EXPORT_SYMBOL(sdio_bt_a_init);
+EXPORT_SYMBOL(sdio_bt_a_start);
+EXPORT_SYMBOL(sdio_bt_a_stop);
+EXPORT_SYMBOL(sdio_bt_a_send);
+EXPORT_SYMBOL(sdio_bt_a_handle_interrupt);
+EXPORT_SYMBOL(sdio_bt_a_set_sleep_state);
diff --git a/unifi_hostsw_linux_147/sdioemb/config.arm-linux.mk b/unifi_hostsw_linux_147/sdioemb/config.arm-linux.mk
new file mode 100644
index 0000000..c06818b
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/config.arm-linux.mk
@@ -0,0 +1,8 @@
+ARCH := arm
+CROSS_COMPILE := arm-linux-
+
+ifeq ($(KDIR),)
+$(error Set KDIR to the kernel tree to build against)
+endif
+
+include config.generic.mk
diff --git a/unifi_hostsw_linux_147/sdioemb/config.debug.mk b/unifi_hostsw_linux_147/sdioemb/config.debug.mk
new file mode 100644
index 0000000..d53451e
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/config.debug.mk
@@ -0,0 +1,4 @@
+EXTRA_DRV_CFLAGS := -DSDD_DEBUG_EVENT_LOG_LEN=8192 -DSDD_DEBUG_DATA_BUFFER_LEN=8192
+export EXTRA_DRV_CFLAGS
+
+include config.generic.mk
diff --git a/unifi_hostsw_linux_147/sdioemb/config.generic.mk b/unifi_hostsw_linux_147/sdioemb/config.generic.mk
new file mode 100644
index 0000000..684f92b
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/config.generic.mk
@@ -0,0 +1,24 @@
+KDIR ?= /lib/modules/$(shell uname -r)/build
+prefix ?= /usr/local
+
+modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR) \
+ O=$(O) V=$(V)
+
+install_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR) modules_install INSTALL_MOD_PATH=$(DESTDIR) \
+ O=$(O) V=$(V)
+
+clean_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR) clean \
+ O=$(O) V=$(V)
+
+ifneq ($(CROSS_COMPILE),)
+export CROSS_COMPILE
+endif
+
+ifneq ($(ARCH),)
+export ARCH
+endif
+
+export prefix
diff --git a/unifi_hostsw_linux_147/sdioemb/fdrv_uif_lx.c b/unifi_hostsw_linux_147/sdioemb/fdrv_uif_lx.c
new file mode 100644
index 0000000..ac8fa00
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/fdrv_uif_lx.c
@@ -0,0 +1,414 @@
+/*
+ * SDIO Userspace Interface driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+#include <asm/uaccess.h>
+
+#include <linux/kernel-compat.h>
+
+#include <linux/sdioemb/uif.h>
+
+#include "sdio_layer.h"
+
+#define UIF_MAX_CARDS 16
+
+struct sdio_uif_dev {
+ struct sdio_dev * fdev;
+ int card_present;
+ struct mutex sdio_mutex;
+ wait_queue_head_t waitq;
+ struct cdev cdev;
+ atomic_t ref_count;
+
+ int interrupt;
+};
+
+static dev_t uif_first_dev;
+static struct class * uif_class;
+
+static void uif_get(struct sdio_uif_dev *ud)
+{
+ atomic_inc(&ud->ref_count);
+}
+
+static void uif_put(struct sdio_uif_dev *ud)
+{
+ if (atomic_dec_and_test(&ud->ref_count)) {
+ kfree(ud);
+ }
+}
+
+
+static inline int uif_num_functions(struct sdio_uif_dev *ud)
+{
+ /*
+ * The number of functions a card has is not available to function
+ * drivers so we have to peek inside the SDIO layer's private
+ * data.
+ */
+ struct sdio_dev_priv *fdevp = ud->fdev->priv;
+ struct sdio_slot_priv *slotp = fdevp->slot->priv;
+
+ return slotp->num_functions;
+}
+
+static int uif_do_cmd(struct sdio_uif_dev *ud, struct sdio_uif_cmd *cmd, uint8_t *data)
+{
+ switch (cmd->type) {
+ case SDD_UIF_CMD52_READ:
+ return ud->fdev->io->read8(ud->fdev, cmd->function, cmd->address, data);
+ case SDD_UIF_CMD52_WRITE:
+ return ud->fdev->io->write8(ud->fdev, cmd->function, cmd->address, *data);
+ case SDD_UIF_CMD53_READ:
+ ud->fdev->blocksize = cmd->block_size;
+ return ud->fdev->io->read(ud->fdev, cmd->function, cmd->address,
+ data, cmd->len);
+ case SDD_UIF_CMD53_WRITE:
+ ud->fdev->blocksize = cmd->block_size;
+ return ud->fdev->io->write(ud->fdev, cmd->function, cmd->address,
+ data, cmd->len);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int uif_wait_for_interrupt(struct sdio_uif_dev *ud)
+{
+ int ret = 0;
+
+ sdio_enable_interrupt(ud->fdev);
+
+ ret = wait_event_interruptible(ud->waitq, ud->interrupt);
+ if (ret) {
+ ret = -ERESTARTSYS;
+ } else {
+ ud->interrupt = 0;
+ }
+
+ sdio_disable_interrupt(ud->fdev);
+
+ return ret;
+}
+
+static int uif_set_bus_width(struct sdio_uif_dev *ud, int bus_width)
+{
+ int ret;
+
+ mutex_lock(&ud->sdio_mutex);
+ ret = sdio_set_bus_width(ud->fdev, bus_width);
+ mutex_unlock(&ud->sdio_mutex);
+
+ return ret;
+}
+
+static int uif_reinsert(struct sdio_uif_dev *ud)
+{
+ struct sdio_dev_priv *fdevp = ud->fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+
+ sdio_card_removed(slot);
+ msleep(100);
+ sdio_card_inserted(slot);
+
+ return 0;
+}
+
+static int uif_set_bus_freq(struct sdio_uif_dev *ud, int bus_freq)
+{
+ struct sdio_dev *fdev = ud->fdev;
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+
+ if (bus_freq < 0 && bus_freq != SDD_BUS_FREQ_DEFAULT) {
+ return -EINVAL;
+ }
+
+ if (bus_freq != SDD_BUS_FREQ_OFF) {
+ sdio_set_max_bus_freq(ud->fdev, bus_freq);
+ bus_freq = slot->clock_freq;
+ }
+
+ /* Set clock rate and start it if it isn't already running at the
+ correct speed. */
+ slot_set_bus_freq(slot, bus_freq);
+
+ return 0;
+}
+
+static int uif_manf_id(struct sdio_uif_dev *ud)
+{
+ return ud->fdev->vendor_id;
+}
+
+static int uif_card_id(struct sdio_uif_dev *ud)
+{
+ return ud->fdev->device_id;
+}
+
+static int uif_get_std_if(struct sdio_uif_dev *ud, unsigned long func)
+{
+ struct sdio_dev_priv *fdevp = ud->fdev->priv;
+ struct sdio_slot_priv *slotp = fdevp->slot->priv;
+
+ return slotp->functions[func]->interface;
+}
+
+static int uif_get_max_block_size(struct sdio_uif_dev *ud, unsigned long func)
+{
+ struct sdio_dev_priv *fdevp = ud->fdev->priv;
+ struct sdio_slot_priv *slotp = fdevp->slot->priv;
+
+ return slotp->functions[func]->max_blocksize;
+}
+
+static int uif_get_block_size(struct sdio_uif_dev *ud, unsigned long func)
+{
+ struct sdio_dev_priv *fdevp = ud->fdev->priv;
+ struct sdio_slot_priv *slotp = fdevp->slot->priv;
+ int blk_sz;
+
+ mutex_lock(&ud->sdio_mutex);
+ blk_sz = slotp->functions[func]->blocksize;
+ mutex_unlock(&ud->sdio_mutex);
+ return blk_sz;
+}
+
+static int uif_set_block_size(struct sdio_uif_dev *ud, unsigned long blksz, unsigned long func)
+{
+ struct sdio_dev_priv *fdevp = ud->fdev->priv;
+ struct sdio_slot_priv *slotp = fdevp->slot->priv;
+ int ret;
+
+ mutex_lock(&ud->sdio_mutex);
+ ret = sdio_set_block_size(slotp->functions[func], blksz);
+ mutex_unlock(&ud->sdio_mutex);
+ return ret;
+}
+
+static int uif_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg)
+{
+ struct sdio_uif_dev *ud = file->private_data;
+ struct sdio_uif_cmd scmd;
+ uint8_t *data;
+ int ret;
+
+ switch (cmd) {
+ case SDD_UIF_IOCQNUMFUNCS:
+ return uif_num_functions(ud);
+ case SDD_UIF_IOCCMD:
+ if (copy_from_user(&scmd, (struct uif_cmd *)arg, sizeof(struct sdio_uif_cmd))) {
+ return -EFAULT;
+ }
+ data = kmalloc(scmd.len, GFP_KERNEL);
+ if (!data) {
+ return -ENOMEM;
+ }
+ if (copy_from_user(data, scmd.data, scmd.len) == 0) {
+ mutex_lock(&ud->sdio_mutex);
+ ret = uif_do_cmd(ud, &scmd, data);
+ mutex_unlock(&ud->sdio_mutex);
+
+ if (!ret && copy_to_user(scmd.data, data, scmd.len)) {
+ ret = -EFAULT;
+ }
+ } else {
+ ret = -EFAULT;
+ }
+ kfree(data);
+ return ret;
+ case SDD_UIF_IOCWAITFORINT:
+ return uif_wait_for_interrupt(ud);
+ case SDD_UIF_IOCTBUSWIDTH:
+ return uif_set_bus_width(ud, arg);
+ case SDD_UIF_IOCREINSERT:
+ return uif_reinsert(ud);
+ case SDD_UIF_IOCTBUSFREQ:
+ return uif_set_bus_freq(ud, (int)arg);
+ case SDD_UIF_IOCQMANFID:
+ return uif_manf_id(ud);
+ case SDD_UIF_IOCQCARDID:
+ return uif_card_id(ud);
+ case SDD_UIF_IOCQSTDIF:
+ return uif_get_std_if(ud, arg);
+ case SDD_UIF_IOCQMAXBLKSZ:
+ return uif_get_max_block_size(ud, arg);
+ case SDD_UIF_IOCQBLKSZ:
+ return uif_get_block_size(ud, arg);
+ case SDD_UIF_IOCTBLKSZ:
+ return uif_set_block_size(ud, arg >> 8, arg & 0xff); /* low octet is function number */
+ default:
+ return -ENOTTY;
+ }
+}
+
+static int uif_open(struct inode *inode, struct file *file)
+{
+ struct sdio_uif_dev *ud = container_of(inode->i_cdev, struct sdio_uif_dev, cdev);
+ int ret = 0;
+
+ mutex_lock(&ud->sdio_mutex);
+
+ if (!ud->card_present)
+ ret = -ENODEV;
+ else {
+ uif_get(ud);
+ file->private_data = ud;
+ }
+
+ mutex_unlock(&ud->sdio_mutex);
+
+ return ret;
+}
+
+static int uif_release(struct inode *inode, struct file *file)
+{
+ struct sdio_uif_dev *ud = container_of(inode->i_cdev, struct sdio_uif_dev, cdev);
+
+ uif_put(ud);
+
+ return 0;
+}
+
+
+static struct file_operations uif_fops = {
+ .owner = THIS_MODULE,
+ .open = uif_open,
+ .release = uif_release,
+ .ioctl = uif_ioctl,
+};
+
+static int uif_probe(struct sdio_dev *fdev)
+{
+ struct sdio_uif_dev *ud;
+ dev_t devno;
+ int ret = -ENOMEM;
+
+ ud = kzalloc(sizeof(struct sdio_uif_dev), GFP_KERNEL);
+ if (!ud)
+ goto error_kzalloc;
+ fdev->drv_data = ud;
+
+ ud->fdev = fdev;
+
+ cdev_init(&ud->cdev, &uif_fops);
+
+ ud->card_present = 1;
+
+ mutex_init(&ud->sdio_mutex);
+ init_waitqueue_head(&ud->waitq);
+
+ atomic_set(&ud->ref_count, 1);
+
+ devno = MKDEV(MAJOR(uif_first_dev), MINOR(uif_first_dev) + ud->fdev->slot_id);
+ ret = cdev_add(&ud->cdev, devno, 1);
+ if (ret)
+ goto error_cdev_add;
+
+ if (!device_create(uif_class, NULL, ud->cdev.dev, NULL, "sdio_uif%d", ud->fdev->slot_id))
+ goto error_device_create;
+
+ return 0;
+
+ error_device_create:
+ cdev_del(&ud->cdev);
+ error_cdev_add:
+ kfree(ud);
+ error_kzalloc:
+ return ret;
+}
+
+static void uif_remove(struct sdio_dev *fdev)
+{
+ struct sdio_uif_dev *ud = fdev->drv_data;
+
+ mutex_lock(&ud->sdio_mutex);
+ ud->card_present = 0;
+ mutex_unlock(&ud->sdio_mutex);
+
+ device_destroy(uif_class, ud->cdev.dev);
+ cdev_del(&ud->cdev);
+ uif_put(ud);
+}
+
+static void uif_int_handler(struct sdio_dev *fdev)
+{
+ struct sdio_uif_dev *ud = fdev->drv_data;
+
+ sdio_disable_interrupt(ud->fdev);
+ ud->interrupt = 1;
+ wake_up_interruptible(&ud->waitq);
+}
+
+static struct sdio_id_table uif_ids[] = {
+ {
+ .vendor_id = SDD_ANY_ID,
+ .device_id = SDD_ANY_ID,
+ .function = SDD_UIF_FUNC,
+ .interface = SDD_ANY_IFACE,
+ },
+ { 0 },
+};
+
+static struct sdio_func_driver uif_driver = {
+ .name = "uif",
+ .id_table = uif_ids,
+
+ .probe = uif_probe,
+ .remove = uif_remove,
+ .card_int_handler = uif_int_handler,
+};
+
+static int __init sdio_uif_init(void)
+{
+ int ret;
+
+ ret = alloc_chrdev_region(&uif_first_dev, 0, UIF_MAX_CARDS, "sdio_uif");
+ if (ret)
+ goto error;
+
+ uif_class = class_create(THIS_MODULE, "sdio_uif");
+ if (!uif_class)
+ goto error;
+
+ ret = sdio_driver_register(&uif_driver);
+ if (ret < 0) {
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ if (uif_class)
+ class_destroy(uif_class);
+ if (uif_first_dev)
+ unregister_chrdev_region(uif_first_dev, UIF_MAX_CARDS);
+ return ret;
+}
+
+static void __exit sdio_uif_exit(void)
+{
+ sdio_driver_unregister(&uif_driver);
+
+ class_destroy(uif_class);
+ unregister_chrdev_region(uif_first_dev, UIF_MAX_CARDS);
+}
+
+module_init(sdio_uif_init);
+module_exit(sdio_uif_exit);
+
+MODULE_DESCRIPTION("SDIO Userspace Interface driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/html/annotated.html b/unifi_hostsw_linux_147/sdioemb/html/annotated.html
new file mode 100644
index 0000000..5dbbb82
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/annotated.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Annotated Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindexHL" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdioemb Data Structures</h1>Here are the data structures with brief descriptions:<table>
+ <tr><td class="indexkey"><a class="el" href="structcspi__cmd__resp.html">cspi_cmd_resp</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structsdio__card__io__ops.html">sdio_card_io_ops</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structsdio__cmd.html">sdio_cmd</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structsdio__cmd__resp.html">sdio_cmd_resp</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structsdio__dev.html">sdio_dev</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structsdio__func__driver.html">sdio_func_driver</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structsdio__id__table.html">sdio_id_table</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="unionsdio__response.html">sdio_response</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structsdio__slot.html">sdio_slot</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey"><a class="el" href="structslot__caps.html">slot_caps</a></td><td class="indexvalue"></td></tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/bug.html b/unifi_hostsw_linux_147/sdioemb/html/bug.html
new file mode 100644
index 0000000..97b15f1
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/bug.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Bug List</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1><a class="anchor" name="bug">Bug List</a></h1><a class="anchor" name="_bug000003"></a> <dl>
+<dt>Global <a class="el" href="structsdio__func__driver.html#o4">sdio_func_driver::card_int_handler</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev) </dt>
+<dd>This will <em>not</em> work correctly with cards with more than one function raising an interrupt. </dd>
+</dl>
+<p>
+<a class="anchor" name="_bug000001"></a> <dl>
+<dt>Class <a class="el" href="unionsdio__response.html">sdio_response</a> </dt>
+<dd>R2 and R3 responses are not used by SDIO and are not supported. </dd>
+</dl>
+<p>
+<a class="anchor" name="_bug000002"></a> <dl>
+<dt>Global <a class="el" href="group__fdriver.html#ga10">sdio_disable_function</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev) </dt>
+<dd>To permit a disable/enable sequence to be used as a per-function reset, disabling a function should wait for I/O Ready to be cleared. </dd>
+</dl>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/cspi_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/cspi_8h-source.html
new file mode 100644
index 0000000..d0cdc9d
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/cspi_8h-source.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/cspi.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/cspi.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * CSPI definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef SDIOEMB_CSPI_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define SDIOEMB_CSPI_H</span>
+00011 <span class="preprocessor"></span>
+00016 <span class="preprocessor">#define CSPI_FUNC(f) (f)</span>
+00017 <span class="preprocessor"></span><span class="preprocessor">#define CSPI_READ 0x10</span>
+00018 <span class="preprocessor"></span><span class="preprocessor">#define CSPI_WRITE 0x20</span>
+00019 <span class="preprocessor"></span><span class="preprocessor">#define CSPI_BURST 0x40</span>
+00020 <span class="preprocessor"></span><span class="preprocessor">#define CSPI_TYPE_MASK 0x70</span>
+00021 <span class="preprocessor"></span>
+<a name="l00029"></a><a class="code" href="group__sdriver.html#ga15">00029</a> <span class="preprocessor">#define CSPI_MODE 0xf7</span>
+00030 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_MODE_PADDED_WRITE_HDRS (1 &lt;&lt; 7)</span>
+00031 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_MODE_PADDED_READ_HDRS (1 &lt;&lt; 6)</span>
+00032 <span class="preprocessor"></span>
+<a name="l00040"></a><a class="code" href="group__sdriver.html#ga18">00040</a> <span class="preprocessor"># define CSPI_MODE_BE_REG (1 &lt;&lt; 5)</span>
+00041 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_MODE_BE_BURST (1 &lt;&lt; 4)</span>
+00042 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_MODE_INT_ACTIVE_HIGH (1 &lt;&lt; 3)</span>
+00043 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_MODE_INT_ON_ERR (1 &lt;&lt; 2)</span>
+00044 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_MODE_LEN_FIELD_PRESENT (1 &lt;&lt; 1)</span>
+00045 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_MODE_DRV_MISO_ON_RISING_CLK (1 &lt;&lt; 0)</span>
+00046 <span class="preprocessor"></span>
+00047 <span class="preprocessor">#define CSPI_STATUS 0xf8</span>
+00048 <span class="preprocessor"></span>
+00049 <span class="preprocessor">#define CSPI_PADDING 0xf9</span>
+00050 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_PADDING_REG(p) ((p) &lt;&lt; 0)</span>
+00051 <span class="preprocessor"></span><span class="preprocessor"># define CSPI_PADDING_BURST(p) ((p) &lt;&lt; 4)</span>
+00052 <span class="preprocessor"></span>
+00053 <span class="preprocessor">#define CSPI_PADDING_MAX 15</span>
+00054 <span class="preprocessor"></span><span class="preprocessor">#define CSPI_PADDING_REG_DFLT 0</span>
+00055 <span class="preprocessor"></span><span class="preprocessor">#define CSPI_PADDING_BURST_DFLT 2</span>
+00056 <span class="preprocessor"></span>
+00057 <span class="comment">/* cmd byte, 3 byte addr, padding, error byte, data word */</span>
+00058 <span class="preprocessor">#define CSPI_REG_TRANSFER_LEN (1 + 3 + CSPI_PADDING_MAX + 1 + 2)</span>
+00059 <span class="preprocessor"></span>
+00062 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef SDIOEMB_CSPI_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/deprecated.html b/unifi_hostsw_linux_147/sdioemb/html/deprecated.html
new file mode 100644
index 0000000..dbd07d0
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/deprecated.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Deprecated List</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1><a class="anchor" name="deprecated">Deprecated List</a></h1><a class="anchor" name="_deprecated000001"></a> <dl>
+<dt>Global <a class="el" href="structsdio__dev.html#o7">sdio_dev::io</a> </dt>
+<dd>See <a class="el" href="group__fdriver.html#card_io_ops">Card I/O Operations</a>. </dd>
+</dl>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/doxygen.css b/unifi_hostsw_linux_147/sdioemb/html/doxygen.css
new file mode 100644
index 0000000..a89dd24
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/doxygen.css
@@ -0,0 +1,169 @@
+H1 {
+ text-align: center;
+ font-family: Arial, Helvetica, sans-serif;
+}
+H2 {
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+CAPTION { font-weight: bold }
+DIV.qindex { width: 100%;
+ background-color: #eeeeff;
+ border: 4px solid #eeeeff;
+ text-align: center;
+ margin-bottom: 2px
+}
+A.qindex { text-decoration: none; font-weight: bold; color: #0000ee }
+A.qindex:visited { text-decoration: none; font-weight: bold; color: #0000ee }
+A.qindex:hover { text-decoration: none; background-color: #ddddff }
+A.qindexHL { text-decoration: none; font-weight: bold;
+ background-color: #6666cc;
+ color: #ffffff
+ }
+A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { font-weight: bold }
+A.code { text-decoration: none; font-weight: normal; color: #4444ee }
+A.codeRef { font-weight: normal; color: #4444ee }
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+DIV.fragment {
+ width: 98%;
+ border: 1px solid #CCCCCC;
+ background-color: #f5f5f5;
+ padding-left: 4px;
+ margin: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+TD.md { background-color: #f2f2ff; font-weight: bold; }
+TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; }
+TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; }
+DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
+BODY {
+ background: white;
+ color: black;
+ margin-right: 20px;
+ margin-left: 20px;
+}
+TD.indexkey {
+ background-color: #eeeeff;
+ font-weight: bold;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px
+}
+TD.indexvalue {
+ background-color: #eeeeff;
+ font-style: italic;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px
+}
+TR.memlist {
+ background-color: #f0f0f0;
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword { color: #008000 }
+SPAN.keywordtype { color: #604020 }
+SPAN.keywordflow { color: #e08000 }
+SPAN.comment { color: #800000 }
+SPAN.preprocessor { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral { color: #008080 }
+.mdTable {
+ border: 1px solid #868686;
+ background-color: #f2f2ff;
+}
+.mdRow {
+ padding: 8px 20px;
+}
+.mdescLeft {
+ font-size: smaller;
+ font-family: Arial, Helvetica, sans-serif;
+ background-color: #FAFAFA;
+ padding-left: 8px;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+}
+.mdescRight {
+ font-size: smaller;
+ font-family: Arial, Helvetica, sans-serif;
+ font-style: italic;
+ background-color: #FAFAFA;
+ padding-left: 4px;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+ padding-bottom: 0px;
+ padding-right: 8px;
+}
+.memItemLeft {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-style: solid;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+}
+.memItemRight {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-style: solid;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+ font-size: 13px;
+}
+.search { color: #0000ee;
+ font-weight: bold;
+}
+FORM.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #eeeeff;
+}
+TD.tiny { font-size: 75%;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/html/doxygen.png b/unifi_hostsw_linux_147/sdioemb/html/doxygen.png
new file mode 100644
index 0000000..9da55f9
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/doxygen.png
Binary files differ
diff --git a/unifi_hostsw_linux_147/sdioemb/html/files.html b/unifi_hostsw_linux_147/sdioemb/html/files.html
new file mode 100644
index 0000000..c763e74
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/files.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: File Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindexHL" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdioemb File List</h1>Here is a list of all documented files with brief descriptions:<table>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>sdio_config.h</b> <a href="sdio__config_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>sdio_event_log.h</b> <a href="sdio__event__log_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>sdio_layer.h</b> <a href="sdio__layer_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_imx27.h</b> <a href="slot__imx27_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_imx27_lx.h</b> <a href="slot__imx27__lx_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_imx31.h</b> <a href="slot__imx31_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_imx31_lx.h</b> <a href="slot__imx31__lx_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_pxa27x.h</b> <a href="slot__pxa27x_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_pxa27x_lx.h</b> <a href="slot__pxa27x__lx_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_shc.h</b> <a href="slot__shc_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/<b>slot_spi_lx.h</b> <a href="slot__spi__lx_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/linux/sdioemb/<b>uif.h</b> <a href="uif_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>cspi.h</b> <a href="cspi_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>libsdio.h</b> <a href="libsdio_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>sdio.h</b> <a href="sdio_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>sdio_api.h</b> <a href="sdio__api_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>sdio_bt_a.h</b> <a href="sdio__bt__a_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>sdio_cis.h</b> <a href="sdio__cis_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>sdio_csr.h</b> <a href="sdio__csr_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<b>slot_api.h</b> <a href="slot__api_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/libsdio/<b>libsdio_internal.h</b> <a href="libsdio__internal_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+ <tr><td class="indexkey">/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/tests/<b>sdd_test.h</b> <a href="sdd__test_8h-source.html">[code]</a></td><td class="indexvalue"></td></tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/functions.html b/unifi_hostsw_linux_147/sdioemb/html/functions.html
new file mode 100644
index 0000000..7910bd6
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/functions.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Compound Member Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindexHL" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<div class="qindex"><a class="qindexHL" href="functions.html">All</a> | <a class="qindex" href="functions_vars.html">Variables</a></div>
+<div class="qindex"><a class="qindex" href="#index_a">a</a> | <a class="qindex" href="#index_b">b</a> | <a class="qindex" href="#index_c">c</a> | <a class="qindex" href="#index_d">d</a> | <a class="qindex" href="#index_e">e</a> | <a class="qindex" href="#index_f">f</a> | <a class="qindex" href="#index_h">h</a> | <a class="qindex" href="#index_i">i</a> | <a class="qindex" href="#index_l">l</a> | <a class="qindex" href="#index_m">m</a> | <a class="qindex" href="#index_n">n</a> | <a class="qindex" href="#index_o">o</a> | <a class="qindex" href="#index_p">p</a> | <a class="qindex" href="#index_r">r</a> | <a class="qindex" href="#index_s">s</a> | <a class="qindex" href="#index_t">t</a> | <a class="qindex" href="#index_v">v</a></div>
+
+<p>
+
+<p>
+Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:<h3><a class="anchor" name="index_a">- a -</a></h3><ul>
+<li>addr
+: <a class="el" href="structcspi__cmd__resp.html#o1">cspi_cmd_resp</a><li>arg
+: <a class="el" href="structsdio__cmd__resp.html#o1">sdio_cmd_resp</a></ul>
+<h3><a class="anchor" name="index_b">- b -</a></h3><ul>
+<li>blocksize
+: <a class="el" href="structsdio__dev.html#o6">sdio_dev</a><li>bus_width
+: <a class="el" href="structsdio__slot.html#o12">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_c">- c -</a></h3><ul>
+<li>callback
+: <a class="el" href="structsdio__cmd.html#o1">sdio_cmd</a><li>caps
+: <a class="el" href="structsdio__slot.html#o10">sdio_slot</a><li>card_int_handler
+: <a class="el" href="structsdio__func__driver.html#o4">sdio_func_driver</a><li>card_power
+: <a class="el" href="structsdio__slot.html#o6">sdio_slot</a><li>card_present
+: <a class="el" href="structsdio__slot.html#o5">sdio_slot</a><li>clock_freq
+: <a class="el" href="structsdio__slot.html#o11">sdio_slot</a><li>cmd
+: <a class="el" href="structcspi__cmd__resp.html#o0">cspi_cmd_resp</a>, <a class="el" href="structsdio__cmd__resp.html#o0">sdio_cmd_resp</a><li>cspi
+: <a class="el" href="structsdio__cmd.html#o4">sdio_cmd</a><li>cspi_burst_pad
+: <a class="el" href="structsdio__slot.html#o14">sdio_slot</a><li>cspi_mode
+: <a class="el" href="structslot__caps.html#o2">slot_caps</a><li>cspi_reg_pad
+: <a class="el" href="structsdio__slot.html#o13">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_d">- d -</a></h3><ul>
+<li>data
+: <a class="el" href="structsdio__cmd.html#o5">sdio_cmd</a><li>device_id
+: <a class="el" href="structsdio__id__table.html#o1">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o2">sdio_dev</a><li>disable_card_int
+: <a class="el" href="structsdio__slot.html#o8">sdio_slot</a><li>driver
+: <a class="el" href="structsdio__dev.html#o0">sdio_dev</a><li>drv_data
+: <a class="el" href="structsdio__slot.html#o16">sdio_slot</a>, <a class="el" href="structsdio__dev.html#o11">sdio_dev</a></ul>
+<h3><a class="anchor" name="index_e">- e -</a></h3><ul>
+<li>enable_card_int
+: <a class="el" href="structsdio__slot.html#o7">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_f">- f -</a></h3><ul>
+<li>flags
+: <a class="el" href="structsdio__cmd.html#o2">sdio_cmd</a><li>function
+: <a class="el" href="structsdio__id__table.html#o2">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o3">sdio_dev</a></ul>
+<h3><a class="anchor" name="index_h">- h -</a></h3><ul>
+<li>hard_reset
+: <a class="el" href="structsdio__slot.html#o9">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_i">- i -</a></h3><ul>
+<li>id_table
+: <a class="el" href="structsdio__func__driver.html#o1">sdio_func_driver</a><li>interface
+: <a class="el" href="structsdio__id__table.html#o3">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o4">sdio_dev</a><li>io
+: <a class="el" href="structsdio__dev.html#o7">sdio_dev</a></ul>
+<h3><a class="anchor" name="index_l">- l -</a></h3><ul>
+<li>len
+: <a class="el" href="structsdio__cmd.html#o6">sdio_cmd</a></ul>
+<h3><a class="anchor" name="index_m">- m -</a></h3><ul>
+<li>max_blocksize
+: <a class="el" href="structsdio__dev.html#o5">sdio_dev</a><li>max_bus_freq
+: <a class="el" href="structslot__caps.html#o0">slot_caps</a><li>max_bus_width
+: <a class="el" href="structslot__caps.html#o1">slot_caps</a></ul>
+<h3><a class="anchor" name="index_n">- n -</a></h3><ul>
+<li>name
+: <a class="el" href="structsdio__slot.html#o0">sdio_slot</a>, <a class="el" href="structsdio__func__driver.html#o0">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_o">- o -</a></h3><ul>
+<li>os_device
+: <a class="el" href="structsdio__dev.html#o9">sdio_dev</a><li>owner
+: <a class="el" href="structsdio__cmd.html#o0">sdio_cmd</a></ul>
+<h3><a class="anchor" name="index_p">- p -</a></h3><ul>
+<li>priv
+: <a class="el" href="structsdio__slot.html#o15">sdio_slot</a>, <a class="el" href="structsdio__cmd.html#o8">sdio_cmd</a>, <a class="el" href="structsdio__dev.html#o10">sdio_dev</a><li>probe
+: <a class="el" href="structsdio__func__driver.html#o2">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_r">- r -</a></h3><ul>
+<li>remove
+: <a class="el" href="structsdio__func__driver.html#o3">sdio_func_driver</a><li>response
+: <a class="el" href="structcspi__cmd__resp.html#o3">cspi_cmd_resp</a>, <a class="el" href="structsdio__cmd__resp.html#o2">sdio_cmd_resp</a><li>resume
+: <a class="el" href="structsdio__func__driver.html#o6">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_s">- s -</a></h3><ul>
+<li>sdio
+: <a class="el" href="structsdio__cmd.html#o3">sdio_cmd</a><li>set_bus_freq
+: <a class="el" href="structsdio__slot.html#o2">sdio_slot</a><li>set_bus_width
+: <a class="el" href="structsdio__slot.html#o3">sdio_slot</a><li>slot_id
+: <a class="el" href="structsdio__dev.html#o8">sdio_dev</a><li>start_cmd
+: <a class="el" href="structsdio__slot.html#o4">sdio_slot</a><li>status
+: <a class="el" href="structsdio__cmd.html#o7">sdio_cmd</a><li>suspend
+: <a class="el" href="structsdio__func__driver.html#o5">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_t">- t -</a></h3><ul>
+<li>type
+: <a class="el" href="structsdio__slot.html#o1">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_v">- v -</a></h3><ul>
+<li>val
+: <a class="el" href="structcspi__cmd__resp.html#o2">cspi_cmd_resp</a><li>vendor_id
+: <a class="el" href="structsdio__id__table.html#o0">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o1">sdio_dev</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/functions_vars.html b/unifi_hostsw_linux_147/sdioemb/html/functions_vars.html
new file mode 100644
index 0000000..c993c67
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/functions_vars.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Compound Member Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindexHL" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<div class="qindex"><a class="qindex" href="functions.html">All</a> | <a class="qindexHL" href="functions_vars.html">Variables</a></div>
+<div class="qindex"><a class="qindex" href="#index_a">a</a> | <a class="qindex" href="#index_b">b</a> | <a class="qindex" href="#index_c">c</a> | <a class="qindex" href="#index_d">d</a> | <a class="qindex" href="#index_e">e</a> | <a class="qindex" href="#index_f">f</a> | <a class="qindex" href="#index_h">h</a> | <a class="qindex" href="#index_i">i</a> | <a class="qindex" href="#index_l">l</a> | <a class="qindex" href="#index_m">m</a> | <a class="qindex" href="#index_n">n</a> | <a class="qindex" href="#index_o">o</a> | <a class="qindex" href="#index_p">p</a> | <a class="qindex" href="#index_r">r</a> | <a class="qindex" href="#index_s">s</a> | <a class="qindex" href="#index_t">t</a> | <a class="qindex" href="#index_v">v</a></div>
+
+<p>
+
+<p>
+<h3><a class="anchor" name="index_a">- a -</a></h3><ul>
+<li>addr
+: <a class="el" href="structcspi__cmd__resp.html#o1">cspi_cmd_resp</a><li>arg
+: <a class="el" href="structsdio__cmd__resp.html#o1">sdio_cmd_resp</a></ul>
+<h3><a class="anchor" name="index_b">- b -</a></h3><ul>
+<li>blocksize
+: <a class="el" href="structsdio__dev.html#o6">sdio_dev</a><li>bus_width
+: <a class="el" href="structsdio__slot.html#o12">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_c">- c -</a></h3><ul>
+<li>callback
+: <a class="el" href="structsdio__cmd.html#o1">sdio_cmd</a><li>caps
+: <a class="el" href="structsdio__slot.html#o10">sdio_slot</a><li>card_int_handler
+: <a class="el" href="structsdio__func__driver.html#o4">sdio_func_driver</a><li>card_power
+: <a class="el" href="structsdio__slot.html#o6">sdio_slot</a><li>card_present
+: <a class="el" href="structsdio__slot.html#o5">sdio_slot</a><li>clock_freq
+: <a class="el" href="structsdio__slot.html#o11">sdio_slot</a><li>cmd
+: <a class="el" href="structcspi__cmd__resp.html#o0">cspi_cmd_resp</a>, <a class="el" href="structsdio__cmd__resp.html#o0">sdio_cmd_resp</a><li>cspi
+: <a class="el" href="structsdio__cmd.html#o4">sdio_cmd</a><li>cspi_burst_pad
+: <a class="el" href="structsdio__slot.html#o14">sdio_slot</a><li>cspi_mode
+: <a class="el" href="structslot__caps.html#o2">slot_caps</a><li>cspi_reg_pad
+: <a class="el" href="structsdio__slot.html#o13">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_d">- d -</a></h3><ul>
+<li>data
+: <a class="el" href="structsdio__cmd.html#o5">sdio_cmd</a><li>device_id
+: <a class="el" href="structsdio__id__table.html#o1">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o2">sdio_dev</a><li>disable_card_int
+: <a class="el" href="structsdio__slot.html#o8">sdio_slot</a><li>driver
+: <a class="el" href="structsdio__dev.html#o0">sdio_dev</a><li>drv_data
+: <a class="el" href="structsdio__slot.html#o16">sdio_slot</a>, <a class="el" href="structsdio__dev.html#o11">sdio_dev</a></ul>
+<h3><a class="anchor" name="index_e">- e -</a></h3><ul>
+<li>enable_card_int
+: <a class="el" href="structsdio__slot.html#o7">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_f">- f -</a></h3><ul>
+<li>flags
+: <a class="el" href="structsdio__cmd.html#o2">sdio_cmd</a><li>function
+: <a class="el" href="structsdio__id__table.html#o2">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o3">sdio_dev</a></ul>
+<h3><a class="anchor" name="index_h">- h -</a></h3><ul>
+<li>hard_reset
+: <a class="el" href="structsdio__slot.html#o9">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_i">- i -</a></h3><ul>
+<li>id_table
+: <a class="el" href="structsdio__func__driver.html#o1">sdio_func_driver</a><li>interface
+: <a class="el" href="structsdio__id__table.html#o3">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o4">sdio_dev</a><li>io
+: <a class="el" href="structsdio__dev.html#o7">sdio_dev</a></ul>
+<h3><a class="anchor" name="index_l">- l -</a></h3><ul>
+<li>len
+: <a class="el" href="structsdio__cmd.html#o6">sdio_cmd</a></ul>
+<h3><a class="anchor" name="index_m">- m -</a></h3><ul>
+<li>max_blocksize
+: <a class="el" href="structsdio__dev.html#o5">sdio_dev</a><li>max_bus_freq
+: <a class="el" href="structslot__caps.html#o0">slot_caps</a><li>max_bus_width
+: <a class="el" href="structslot__caps.html#o1">slot_caps</a></ul>
+<h3><a class="anchor" name="index_n">- n -</a></h3><ul>
+<li>name
+: <a class="el" href="structsdio__slot.html#o0">sdio_slot</a>, <a class="el" href="structsdio__func__driver.html#o0">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_o">- o -</a></h3><ul>
+<li>os_device
+: <a class="el" href="structsdio__dev.html#o9">sdio_dev</a><li>owner
+: <a class="el" href="structsdio__cmd.html#o0">sdio_cmd</a></ul>
+<h3><a class="anchor" name="index_p">- p -</a></h3><ul>
+<li>priv
+: <a class="el" href="structsdio__slot.html#o15">sdio_slot</a>, <a class="el" href="structsdio__cmd.html#o8">sdio_cmd</a>, <a class="el" href="structsdio__dev.html#o10">sdio_dev</a><li>probe
+: <a class="el" href="structsdio__func__driver.html#o2">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_r">- r -</a></h3><ul>
+<li>remove
+: <a class="el" href="structsdio__func__driver.html#o3">sdio_func_driver</a><li>response
+: <a class="el" href="structcspi__cmd__resp.html#o3">cspi_cmd_resp</a>, <a class="el" href="structsdio__cmd__resp.html#o2">sdio_cmd_resp</a><li>resume
+: <a class="el" href="structsdio__func__driver.html#o6">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_s">- s -</a></h3><ul>
+<li>sdio
+: <a class="el" href="structsdio__cmd.html#o3">sdio_cmd</a><li>set_bus_freq
+: <a class="el" href="structsdio__slot.html#o2">sdio_slot</a><li>set_bus_width
+: <a class="el" href="structsdio__slot.html#o3">sdio_slot</a><li>slot_id
+: <a class="el" href="structsdio__dev.html#o8">sdio_dev</a><li>start_cmd
+: <a class="el" href="structsdio__slot.html#o4">sdio_slot</a><li>status
+: <a class="el" href="structsdio__cmd.html#o7">sdio_cmd</a><li>suspend
+: <a class="el" href="structsdio__func__driver.html#o5">sdio_func_driver</a></ul>
+<h3><a class="anchor" name="index_t">- t -</a></h3><ul>
+<li>type
+: <a class="el" href="structsdio__slot.html#o1">sdio_slot</a></ul>
+<h3><a class="anchor" name="index_v">- v -</a></h3><ul>
+<li>val
+: <a class="el" href="structcspi__cmd__resp.html#o2">cspi_cmd_resp</a><li>vendor_id
+: <a class="el" href="structsdio__id__table.html#o0">sdio_id_table</a>, <a class="el" href="structsdio__dev.html#o1">sdio_dev</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/group__config.html b/unifi_hostsw_linux_147/sdioemb/html/group__config.html
new file mode 100644
index 0000000..6b496ef
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/group__config.html
@@ -0,0 +1,213 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Compile-time configuration</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>Compile-time configuration</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Defines</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga0">SDD_SLOTS_MAX</a>&nbsp;&nbsp;&nbsp;4</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga1">SDD_FDRIVERS_MAX</a>&nbsp;&nbsp;&nbsp;4</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga2">SDD_FDEVS_MAX</a>&nbsp;&nbsp;&nbsp;8</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga3">SDD_CARD_INIT_RETRY_MAX</a>&nbsp;&nbsp;&nbsp;3</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga4">SDD_CARD_READY_TIMEOUT_MS</a>&nbsp;&nbsp;&nbsp;100</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga5">SDD_CARD_IS_REMOVABLE</a>&nbsp;&nbsp;&nbsp;1</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga6">SDD_CSPI_REG_PADDING</a>&nbsp;&nbsp;&nbsp;0</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__config.html#ga7">SDD_CSPI_BURST_PADDING</a>&nbsp;&nbsp;&nbsp;2</td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+Various compile time options are set with #define's. These may be overridden by providing appropriate compiler options (e.g., with gcc's -D option).<p>
+Defaults are provided in <a class="el" href="sdio__config_8h.html">sdio_config.h</a>. <hr><h2>Define Documentation</h2>
+<a class="anchor" name="ga3" doxytag="sdio_config.h::SDD_CARD_INIT_RETRY_MAX" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CARD_INIT_RETRY_MAX&nbsp;&nbsp;&nbsp;3
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Maximum number of times to try to initialize a card. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga5" doxytag="sdio_config.h::SDD_CARD_IS_REMOVABLE" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CARD_IS_REMOVABLE&nbsp;&nbsp;&nbsp;1
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Non-zero if the card is removable, zero if the card is always inserted (e.g., it's wired directly to the SD host controller).<p>
+A thread is used when detecting removable cards. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="sdio_config.h::SDD_CARD_READY_TIMEOUT_MS" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CARD_READY_TIMEOUT_MS&nbsp;&nbsp;&nbsp;100
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Time (in ms) to wait for the card to become ready during the initialization sequence. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga7" doxytag="sdio_config.h::SDD_CSPI_BURST_PADDING" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CSPI_BURST_PADDING&nbsp;&nbsp;&nbsp;2
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Amount of CSPI burst padding in octets. The default of 2 should be fine for all chips and bus speeds less than 25 MHz. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga6" doxytag="sdio_config.h::SDD_CSPI_REG_PADDING" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CSPI_REG_PADDING&nbsp;&nbsp;&nbsp;0
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Amount of CSPI register padding in octets. The default of 0 should be fine for all chips and bus speeds less than 25 MHz. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="sdio_config.h::SDD_FDEVS_MAX" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_FDEVS_MAX&nbsp;&nbsp;&nbsp;8
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Maximum number of functions supported by the core. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="sdio_config.h::SDD_FDRIVERS_MAX" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_FDRIVERS_MAX&nbsp;&nbsp;&nbsp;4
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Maxium number of function drivers that may be registered with the core. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga0" doxytag="sdio_config.h::SDD_SLOTS_MAX" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_SLOTS_MAX&nbsp;&nbsp;&nbsp;4
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Maximum number of SDIO slots that may be registered with the core. </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/group__fdriver.html b/unifi_hostsw_linux_147/sdioemb/html/group__fdriver.html
new file mode 100644
index 0000000..0898a79
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/group__fdriver.html
@@ -0,0 +1,1598 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: SDIO function driver API</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>SDIO function driver API</h1>The SDIO function driver API is used to implement drivers for SDIO card functions.
+<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>struct &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__card__io__ops.html">sdio_card_io_ops</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>struct &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html">sdio_cmd</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>struct &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html">sdio_dev</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>struct &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html">sdio_func_driver</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>struct &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__id__table.html">sdio_id_table</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>union &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="unionsdio__response.html">sdio_response</a></td></tr>
+
+<tr><td colspan=2><br><h2>Defines</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga25">SDD_CMD_FLAG_RESP_NONE</a>&nbsp;&nbsp;&nbsp;0x00</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga26">SDD_CMD_FLAG_RESP_R1</a>&nbsp;&nbsp;&nbsp;0x01</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga27">SDD_CMD_FLAG_RESP_R1B</a>&nbsp;&nbsp;&nbsp;0x02</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga28">SDD_CMD_FLAG_RESP_R2</a>&nbsp;&nbsp;&nbsp;0x03</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga29">SDD_CMD_FLAG_RESP_R3</a>&nbsp;&nbsp;&nbsp;0x04</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga30">SDD_CMD_FLAG_RESP_R4</a>&nbsp;&nbsp;&nbsp;0x05</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga31">SDD_CMD_FLAG_RESP_R5</a>&nbsp;&nbsp;&nbsp;0x06</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga32">SDD_CMD_FLAG_RESP_R5B</a>&nbsp;&nbsp;&nbsp;0x07</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga33">SDD_CMD_FLAG_RESP_R6</a>&nbsp;&nbsp;&nbsp;0x08</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga34">SDD_CMD_FLAG_RESP_MASK</a>&nbsp;&nbsp;&nbsp;0xff</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga35" doxytag="fdriver::SDD_CMD_FLAG_RAW" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>SDD_CMD_FLAG_RAW</b>&nbsp;&nbsp;&nbsp;0x0100</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga36">SDD_CMD_FLAG_READ</a>&nbsp;&nbsp;&nbsp;0x0200</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga37">SDD_CMD_FLAG_CSPI</a>&nbsp;&nbsp;&nbsp;0x0400</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga38">SDD_CMD_FLAG_ABORT</a>&nbsp;&nbsp;&nbsp;0x0800</td></tr>
+
+<tr><td colspan=2><br><h2>Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga0">sdio_card_io_read8_t</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, uint8_t *data)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga1">sdio_card_io_write8_t</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, uint8_t data)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga2">sdio_card_io_read_t</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, uint8_t *data, size_t len)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga3">sdio_card_io_write_t</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, const uint8_t *data, size_t len)</td></tr>
+
+<tr><td colspan=2><br><h2>Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>enum &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga39">sdio_cmd_status</a> { <br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a24">SDD_CMD_OK</a> = 0x00,
+<br>
+&nbsp;&nbsp;<b>SDD_CMD_ERR_CMD</b> = 0x01,
+<br>
+&nbsp;&nbsp;<b>SDD_CMD_ERR_DAT</b> = 0x02,
+<br>
+&nbsp;&nbsp;<b>SDD_CMD_ERR_CRC</b> = 0x10,
+<br>
+&nbsp;&nbsp;<b>SDD_CMD_ERR_TIMEOUT</b> = 0x20,
+<br>
+&nbsp;&nbsp;<b>SDD_CMD_ERR_OTHER</b> = 0x40,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a30">SDD_CMD_ERR_CMD_CRC</a> = SDD_CMD_ERR_CMD | SDD_CMD_ERR_CRC,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a31">SDD_CMD_ERR_CMD_TIMEOUT</a> = SDD_CMD_ERR_CMD | SDD_CMD_ERR_TIMEOUT,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a32">SDD_CMD_ERR_CMD_OTHER</a> = SDD_CMD_ERR_CMD | SDD_CMD_ERR_OTHER,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a33">SDD_CMD_ERR_DAT_CRC</a> = SDD_CMD_ERR_DAT | SDD_CMD_ERR_CRC,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a34">SDD_CMD_ERR_DAT_TIMEOUT</a> = SDD_CMD_ERR_DAT | SDD_CMD_ERR_TIMEOUT,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a35">SDD_CMD_ERR_DAT_OTHER</a> = SDD_CMD_ERR_DAT | SDD_CMD_ERR_OTHER,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a36">SDD_CMD_ERR_NO_CARD</a> = 0x04,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__fdriver.html#gga39a37">SDD_CMD_IN_PROGRESS</a> = 0xff
+<br>
+ }</td></tr>
+
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga4">sdio_hard_reset</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga5">sdio_cis_get_tuple</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, uint8_t tuple, void *buf, size_t len)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga6">sdio_start_cmd</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *cmd)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga7">sdio_driver_register</a> (struct <a class="el" href="structsdio__func__driver.html">sdio_func_driver</a> *fdriver)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga8">sdio_driver_unregister</a> (struct <a class="el" href="structsdio__func__driver.html">sdio_func_driver</a> *fdriver)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga9">sdio_enable_function</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga10">sdio_disable_function</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga11">sdio_set_block_size</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int blksz)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga12">sdio_idle_function</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga13">sdio_set_max_bus_freq</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int max_freq)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga14">sdio_set_bus_width</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int bus_width)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga15">sdio_enable_interrupt</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga16">sdio_disable_interrupt</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga17">sdio_read8</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t *val)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga18">sdio_write8</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t val)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga19">sdio_f0_read8</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t *val)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga20">sdio_f0_write8</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t val)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga21">sdio_read</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, void *data, size_t len)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga22">sdio_write</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, const void *data, size_t len)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga23">sdio_power_on</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__fdriver.html#ga24">sdio_power_off</a> (struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+The SDIO function driver API is used to implement drivers for SDIO card functions.
+<p>
+Function drivers register with the SDIO driver core (sdio_register_driver()), listing which functions it supports and providing callback functions for card inserts, removes and interrupts.<p>
+<dl compact><dt><b><a class="anchor" name="card_io_ops"></a> Card I/O operations:</b></dt><dd></dd></dl>
+<ul>
+<li><a class="el" href="group__fdriver.html#ga17">sdio_read8()</a></li><li><a class="el" href="group__fdriver.html#ga18">sdio_write8()</a></li><li><a class="el" href="group__fdriver.html#ga19">sdio_f0_read8()</a></li><li><a class="el" href="group__fdriver.html#ga20">sdio_f0_write8()</a></li><li><a class="el" href="group__fdriver.html#ga21">sdio_read()</a></li><li><a class="el" href="group__fdriver.html#ga22">sdio_write()</a> </li></ul>
+<hr><h2>Define Documentation</h2>
+<a class="anchor" name="ga38" doxytag="sdio_api.h::SDD_CMD_FLAG_ABORT" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_ABORT&nbsp;&nbsp;&nbsp;0x0800
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Data transfer abort command. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga37" doxytag="sdio_api.h::SDD_CMD_FLAG_CSPI" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_CSPI&nbsp;&nbsp;&nbsp;0x0400
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+CSPI transfer, not SDIO or SDIO-SPI. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga36" doxytag="sdio_api.h::SDD_CMD_FLAG_READ" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_READ&nbsp;&nbsp;&nbsp;0x0200
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Data transfer is a read, not a write. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga34" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_MASK" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_MASK&nbsp;&nbsp;&nbsp;0xff
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Mask for response type. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga25" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_NONE" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_NONE&nbsp;&nbsp;&nbsp;0x00
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+No response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga26" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R1" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R1&nbsp;&nbsp;&nbsp;0x01
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R1 response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga27" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R1B" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R1B&nbsp;&nbsp;&nbsp;0x02
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R1b response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga28" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R2" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R2&nbsp;&nbsp;&nbsp;0x03
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R2 response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga29" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R3" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R3&nbsp;&nbsp;&nbsp;0x04
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R3 response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga30" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R4" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R4&nbsp;&nbsp;&nbsp;0x05
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R4 response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga31" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R5" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R5&nbsp;&nbsp;&nbsp;0x06
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R5 response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga32" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R5B" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R5B&nbsp;&nbsp;&nbsp;0x07
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R5b response. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga33" doxytag="sdio_api.h::SDD_CMD_FLAG_RESP_R6" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDD_CMD_FLAG_RESP_R6&nbsp;&nbsp;&nbsp;0x08
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+R6 response. </td>
+ </tr>
+</table>
+<hr><h2>Typedef Documentation</h2>
+<a class="anchor" name="ga0" doxytag="sdio_api.h::sdio_card_io_read8_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef int(* <a class="el" href="group__fdriver.html#ga0">sdio_card_io_read8_t</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, uint8_t *data)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read an 8 bit wide card register.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>sdio device to read from. </td></tr>
+ <tr><td valign=top><em>function</em>&nbsp;</td><td>card function number. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>returns the value read.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on an error: -EIO if a low-level transport error occurred (e.g., CRC error), -ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="sdio_api.h::sdio_card_io_read_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef int(* <a class="el" href="group__fdriver.html#ga2">sdio_card_io_read_t</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, uint8_t *data, size_t len)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read a buffer from an 8 bit wide card register/FIFO.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>sdio device to read from. </td></tr>
+ <tr><td valign=top><em>function</em>&nbsp;</td><td>card function number. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer to store the data read. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of the buffer.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on an error: -EIO if a low-level transport error occurred (e.g., CRC error), -ETIMEDOUT if no response or data was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="sdio_api.h::sdio_card_io_write8_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef int(* <a class="el" href="group__fdriver.html#ga1">sdio_card_io_write8_t</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, uint8_t data)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Writes an 8 bit wide register on a card.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>sdio device to write to. </td></tr>
+ <tr><td valign=top><em>function</em>&nbsp;</td><td>card function number. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>value to write.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on an error: -EIO if a low-level transport error occurred (e.g., CRC error), -ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="sdio_api.h::sdio_card_io_write_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef int(* <a class="el" href="group__fdriver.html#ga3">sdio_card_io_write_t</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev, int function, uint32_t addr, const uint8_t *data, size_t len)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Writes a buffer to an 8 bit wide card register/FIFO.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>sdio device to write to. </td></tr>
+ <tr><td valign=top><em>function</em>&nbsp;</td><td>card function number. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer of data to write. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of the buffer.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on an error: -EIO if a low-level transport error occurred (e.g., CRC error), -ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<hr><h2>Enumeration Type Documentation</h2>
+<a class="anchor" name="ga39" doxytag="sdio_api.h::sdio_cmd_status" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> enum <a class="el" href="group__fdriver.html#ga39">sdio_cmd_status</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+SDIO command status. <dl compact><dt><b>Enumeration values: </b></dt><dd>
+<table border=0 cellspacing=2 cellpadding=0>
+<tr><td valign=top><em><a class="anchor" name="gga39a24" doxytag="SDD_CMD_OK" ></a>SDD_CMD_OK</em>&nbsp;</td><td>
+Command successful. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a30" doxytag="SDD_CMD_ERR_CMD_CRC" ></a>SDD_CMD_ERR_CMD_CRC</em>&nbsp;</td><td>
+Response CRC error. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a31" doxytag="SDD_CMD_ERR_CMD_TIMEOUT" ></a>SDD_CMD_ERR_CMD_TIMEOUT</em>&nbsp;</td><td>
+Response time out. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a32" doxytag="SDD_CMD_ERR_CMD_OTHER" ></a>SDD_CMD_ERR_CMD_OTHER</em>&nbsp;</td><td>
+Other response error. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a33" doxytag="SDD_CMD_ERR_DAT_CRC" ></a>SDD_CMD_ERR_DAT_CRC</em>&nbsp;</td><td>
+Data CRC error. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a34" doxytag="SDD_CMD_ERR_DAT_TIMEOUT" ></a>SDD_CMD_ERR_DAT_TIMEOUT</em>&nbsp;</td><td>
+Data receive time out. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a35" doxytag="SDD_CMD_ERR_DAT_OTHER" ></a>SDD_CMD_ERR_DAT_OTHER</em>&nbsp;</td><td>
+Other data error. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a36" doxytag="SDD_CMD_ERR_NO_CARD" ></a>SDD_CMD_ERR_NO_CARD</em>&nbsp;</td><td>
+No card present. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga39a37" doxytag="SDD_CMD_IN_PROGRESS" ></a>SDD_CMD_IN_PROGRESS</em>&nbsp;</td><td>
+Command still in progress. </td></tr>
+</table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga5" doxytag="sdio_cis.c::sdio_cis_get_tuple" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_cis_get_tuple </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>tuple</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>buf</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>size_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>len</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read a CIS tuple.<p>
+Copies the specified function's CIS tuple into a buffer. The tuple ID and link pointer are not copied.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>function to read CIS from. </td></tr>
+ <tr><td valign=top><em>tuple</em>&nbsp;</td><td>ID of tuple to find. </td></tr>
+ <tr><td valign=top><em>buf</em>&nbsp;</td><td>destination buffer for tuple data. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of <em>buf</em>.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error: -ENXIO - no such tuple found, -EINVAL - buffer is shorter than the tuple, -EIO,-ETIMEDOUT - I/O error while reading from card. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga10" doxytag="sdio_func.c::sdio_disable_function" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_disable_function </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Disable the function.<p>
+The function's I/O Enable bit is cleared.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device to disable.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error: -EIO or -ETIMEDOUT - a register access failed.</dd></dl>
+<p>
+<dl compact><dt><b><a class="el" href="bug.html#_bug000002">Bug:</a></b></dt><dd>To permit a disable/enable sequence to be used as a per-function reset, disabling a function should wait for I/O Ready to be cleared. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga16" doxytag="sdio_int.c::sdio_disable_interrupt" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_disable_interrupt </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Prevent this SDIO device from receiving card interrupt signals.<p>
+This only affects the routing of card interrupts from the core.<p>
+Function drivers should ensure they clear any pending interrupts before calling this.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device to disable interrupt routing for.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>See also:</b></dt><dd><a class="el" href="group__fdriver.html#ga55">sdio_enable_interrupt()</a>. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga7" doxytag="sdio_core.c::sdio_driver_register" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_driver_register </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__func__driver.html">sdio_func_driver</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdriver</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Register a function driver with the core.<p>
+If any inserted cards that have functions that match <em>fdriver's</em> list of supported functions then <em>fdriver's</em> probe() function will be called for those functions.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdriver</em>&nbsp;</td><td>the function driver to register.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error: -ENOMEM - maximum number of function drivers are already registered. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga8" doxytag="sdio_core.c::sdio_driver_unregister" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_driver_unregister </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__func__driver.html">sdio_func_driver</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdriver</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Unregister a function driver from the core.<p>
+<em>fdriver's</em> remove() will be called for any SDIO devices currently attached to the driver.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdriver</em>&nbsp;</td><td>the function driver to unregister. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga9" doxytag="sdio_func.c::sdio_enable_function" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_enable_function </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Enable the function.<p>
+The function's I/O Enable bit is set and I/O Ready is polled until it is set.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device to enable.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error: -ETIMEDOUT - time out waiting for I/O Ready to be set, -EIO or -ETIMEDOUT - a register access failed. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga15" doxytag="sdio_int.c::sdio_enable_interrupt" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_enable_interrupt </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Allow this SDIO device to receive card interrupt signals.<p>
+This only affects the routing of card interrupts from the core.<p>
+Callable from: any context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device to enable interrupt routing for.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Note:</b></dt><dd>The core always sets the I/O Enable bits for all functions, so interrupts sources on the card should be enabled and disabled in a function specific manner by the function driver. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga19" doxytag="sdio_io.c::sdio_f0_read8" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_f0_read8 </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>val</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read an 8 bit wide function 0 register.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>an SDIO function of the card. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>val</em>&nbsp;</td><td>returns the value read.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success. <p>
+-EIO if a low-level transport error occurred (e.g., CRC error), <p>
+-ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga20" doxytag="sdio_io.c::sdio_f0_write8" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_f0_write8 </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>val</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write an 8 bit wide function 0 register.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>an SDIO function of the card. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>val</em>&nbsp;</td><td>value to write.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success. <p>
+-EIO if a low-level transport error occurred (e.g., CRC error), <p>
+-ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="sdio_card.c::sdio_hard_reset" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_hard_reset </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Perform a hard reset of the card (if the slot is capable) and reinitialize the card.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>an SDIO device of the card.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 if a hard reset was performed and the card successfully reinitialized. <p>
+1 if the slot is not capable of hard resets. <p>
+-ve if the reinitialization failed. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga12" doxytag="sdio_func.c::sdio_idle_function" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_idle_function </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set the function as idle.<p>
+When all functions are idle the SD bus will be idled.<p>
+Functions are set as active (non-idle) when a command is started.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device to set as idle.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>See also:</b></dt><dd>slot_driver::idle_bus. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga24" doxytag="sdio_pm.c::sdio_power_off" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_power_off </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Allow the card to be powered off.<p>
+If no other function is requesting power, the card is powered off. The driver must call <a class="el" href="group__fdriver.html#ga53">sdio_power_on()</a> before performing any more I/O to the card.<p>
+Interrupts are disabled by calling <a class="el" href="group__fdriver.html#ga56">sdio_disable_interrupt()</a> as the DAT1/INT line may no longer be pulled high when power is removed.<p>
+This is called by the core after calling a function driver's remove() method.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device not requiring power. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga23" doxytag="sdio_pm.c::sdio_power_on" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_power_on </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>fdev</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Request power to the card.<p>
+If the card is not powered, apply power and re-initialize the card. No per-function state of the card is restored and the driver should re-enable the function and perform any other function specific initialization.<p>
+This is called by the core before calling a function driver's probe() method.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device requesting power. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga21" doxytag="sdio_io.c::sdio_read" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_read </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>size_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>len</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read a buffer from an 8 bit wide card register/FIFO.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>SDIO function to read from. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer to store the data read. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of the buffer.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success. <p>
+-EIO if a low-level transport error occurred (e.g., CRC error). <p>
+-ETIMEDOUT if no response or data was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga17" doxytag="sdio_io.c::sdio_read8" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_read8 </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>val</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read an 8 bit wide register.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>SDIO function to read from. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>val</em>&nbsp;</td><td>returns the value read.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success. <p>
+-EIO if a low-level transport error occurred (e.g., CRC error), <p>
+-ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga11" doxytag="sdio_func.c::sdio_set_block_size" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_set_block_size </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>blksz</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set a function's block size.<p>
+The default block size is the largest supported by both the function and the host, with a maximum of 512 to ensure that arbitrarily sized data transfers use the optimal (least) number of commands.<p>
+A driver may call this to override the default block size set by the core. This can be used to set a block size greater than the maximum that reported by the card; it is the driver's responsibility to ensure it uses a value that the card supports.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device. </td></tr>
+ <tr><td valign=top><em>blksz</em>&nbsp;</td><td>new block size or 0 to use the default.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error: -EIO or -ETIMEDOUT - a register access failed. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga14" doxytag="sdio_func.c::sdio_set_bus_width" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_set_bus_width </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>bus_width</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set the SDIO bus to 1 bit or 4 bit mode.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device. </td></tr>
+ <tr><td valign=top><em>bus_width</em>&nbsp;</td><td>the bus width (1 or 4).</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success (or if the slot is in SPI mode). <p>
+-EINVAL if the slot doesn't support the requested mode. <p>
+-EIO, -ETIMEDOUT if an I/O error occured when writing the mode to the card. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga13" doxytag="sdio_func.c::sdio_set_max_bus_freq" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_set_max_bus_freq </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>max_freq</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Limit the bus frequency supported by a function.<p>
+The bus frequency used will be the minimum of:<ul>
+<li>the speed reported by the card,</li><li>the maximum the slot can support,</li><li>the value set by this function for any of the card's functions.</li></ul>
+<p>
+If the frequency to be used is high speed (&gt; 25 MHz), high speed mode will be enabled on the card.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device. </td></tr>
+ <tr><td valign=top><em>max_freq</em>&nbsp;</td><td>maximum frequency in Hz, or 0 for the maximum reported by the card. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga6" doxytag="sdio_cmd.c::sdio_start_cmd" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_start_cmd </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>cmd</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Submit an SDIO command to a device.<p>
+The command will be queued and executed when the card becomes available.<p>
+Each SDIO device has a queue with one entry. Therefore, only one command per SDIO device may be submitted at a time.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the SDIO device submitting the command. </td></tr>
+ <tr><td valign=top><em>cmd</em>&nbsp;</td><td>the command to submit.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd><em>0</em> if the command was queued. <p>
+<em>-EAGAIN</em> if the command queue is full. <p>
+<em>-EINVAL</em> if the data transfer is invalid (unsupported buffer alignment or the length is not a valid byte or block mode transfer).</dd></dl>
+<dl compact><dt><b>See also:</b></dt><dd><a class="el" href="structsdio__dev.html#o7">sdio_dev::io</a> </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga22" doxytag="sdio_io.c::sdio_write" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_write </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>size_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>len</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Writes a buffer to an 8 bit wide card register/FIFO.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>SDIO function to write to. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer of data to write. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of the buffer.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success. <p>
+-EIO if a low-level transport error occurred (e.g., CRC error). <p>
+-ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga18" doxytag="sdio_io.c::sdio_write8" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_write8 </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>fdev</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>val</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write an 8 bit wide register.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>SDIO function to write to. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>val</em>&nbsp;</td><td>value to write.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success. <p>
+-EIO if a low-level transport error occurred (e.g., CRC error), <p>
+-ETIMEDOUT if no response was received. </dd></dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/group__libsdio.html b/unifi_hostsw_linux_147/sdioemb/html/group__libsdio.html
new file mode 100644
index 0000000..4690489
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/group__libsdio.html
@@ -0,0 +1,1357 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Userspace SDIO library (libsdio)</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>Userspace SDIO library (libsdio)</h1><em>libsdio</em> is a Linux C library for accessing SDIO cards.
+<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Typedefs</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef sdio_uif *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga1">sdio_int_handler_t</a> )(<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, void *arg)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>typedef void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a> )(<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, void *arg, int status)</td></tr>
+
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga3">sdio_open</a> (const char *dev_filename, <a class="el" href="group__libsdio.html#ga1">sdio_int_handler_t</a> int_handler, void *arg)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga4">sdio_interrupt_mask</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga5">sdio_interrupt_unmask</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga6">sdio_close</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga7">sdio_num_functions</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga8">sdio_set_bus_width</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int bus_width)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga9">sdio_set_max_bus_freq</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int max_freq)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga10">sdio_manf_id</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga11">sdio_card_id</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint8_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga12">sdio_std_if</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga13">sdio_max_block_size</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga14">sdio_block_size</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga15">sdio_set_block_size</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, int blksz)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga16">sdio_read8</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, uint8_t *data)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga17">sdio_write8</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, uint8_t data)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga18">sdio_read</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, uint8_t *data, size_t len, int block_size)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga19">sdio_write</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, const uint8_t *data, size_t len, int block_size)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga20">sdio_read8_async</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, uint8_t *data, <a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, void *arg)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga21">sdio_write8_async</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, uint8_t data, <a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, void *arg)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga22">sdio_read_async</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, uint8_t *data, size_t len, int block_size, <a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, void *arg)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga23">sdio_write_async</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, int func, uint32_t addr, const uint8_t *data, size_t len, int block_size, <a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, void *arg)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__libsdio.html#ga24">sdio_reinsert_card</a> (<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif)</td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+<em>libsdio</em> is a Linux C library for accessing SDIO cards.
+<p>
+Use of this library requires several <em>sdioemb</em> kernel modules to be loaded:<ul>
+<li><code>sdio</code>.</li><li><code>An</code> SDIO slot driver (e.g., <code>slot_shc</code> for a standard PCI SDIO Host Controller).</li><li><code>sdio_uif</code> which provides the required character devices (/dev/sdio_uif0 for the card in SDIO slot 0 etc.). </li></ul>
+<hr><h2>Typedef Documentation</h2>
+<a class="anchor" name="ga1" doxytag="libsdio.h::sdio_int_handler_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef void(* <a class="el" href="group__libsdio.html#ga1">sdio_int_handler_t</a>)(<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, void *arg)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Card interrupt handler function.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>handle to the interrupting device. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>data supplied by the caller of sdio_open(). </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="libsdio.h::sdio_io_callback_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef void(* <a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a>)(<a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, void *arg, int status)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Asynchronous IO completion callback function.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>handle to the device that completed the IO operation. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>data supplied by the caller of the asynchronous IO operation. </td></tr>
+ <tr><td valign=top><em>status</em>&nbsp;</td><td>status of the IO operation. 0 is success; -EIO, -EINVAL, -ETIMEDOUT etc. on an error. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga0" doxytag="libsdio.h::sdio_uif_t" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> typedef struct sdio_uif* <a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Handle to an opened SDIO Userspace Interface device. </td>
+ </tr>
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga14" doxytag="libsdio.h::sdio_block_size" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_block_size </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return a function's current block size.<p>
+<dl compact><dt><b>Note:</b></dt><dd>This returns the driver's view of the block size and not the value in the function's block size register.</dd></dl>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function to query.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>the current block size. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga11" doxytag="libsdio.h::sdio_card_id" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t sdio_card_id </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>uif</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return the card's card (device) ID.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>card ID. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga6" doxytag="libsdio.h::sdio_close" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_close </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>uif</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Close an opened SDIO Userspace Interface device, freeing all associated resources.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>handle to the device. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="libsdio.h::sdio_interrupt_mask" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_interrupt_mask </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>uif</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Mask the SDIO interrupt.<p>
+Call this in an interrupt handler to allow the processing of interrupts to be deferred until after the interrupt handler has returned.<p>
+<dl compact><dt><b>Note:</b></dt><dd><em>Must</em> only be called from within the interrupt handler registered with sdio_open().</dd></dl>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga5" doxytag="libsdio.h::sdio_interrupt_unmask" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_interrupt_unmask </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>uif</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Unmask the SDIO interrupt.<p>
+Unmasks the SDIO interrupt if it had previously been masked with <a class="el" href="group__libsdio.html#ga4">sdio_interrupt_mask()</a>.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga10" doxytag="libsdio.h::sdio_manf_id" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t sdio_manf_id </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>uif</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return the card's manufacturer (vendor) ID.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>manufacturer ID. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga13" doxytag="libsdio.h::sdio_max_block_size" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_max_block_size </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return a function's maximum supported block size.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function to query.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>maximum block size. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga7" doxytag="libsdio.h::sdio_num_functions" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_num_functions </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>uif</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return the number of functions the card has.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>number of card functions. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="libsdio.h::sdio_open" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> <a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a> sdio_open </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">const char *&nbsp;</td>
+ <td class="mdname" nowrap> <em>dev_filename</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap><a class="el" href="group__libsdio.html#ga1">sdio_int_handler_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>int_handler</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>arg</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Open a SDIO Userspace Interface device and (optionally) register a card interrupt handler and enable card interrupts.<p>
+Card interrupts are masked before calling int_handler and are unmasked when int_handler returns (unless <a class="el" href="group__libsdio.html#ga4">sdio_interrupt_mask()</a> is called).<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>dev_filename</em>&nbsp;</td><td>filename of the device to open. </td></tr>
+ <tr><td valign=top><em>int_handler</em>&nbsp;</td><td>card interrupt handler; or NULL if no interrupt handler is required. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>argument to be passed to the interrupt handler.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>handle to the opened device; or NULL on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga18" doxytag="libsdio.h::sdio_read" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_read </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>size_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>len</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>block_size</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read a buffer from a 8 bit wide register/FIFO.<p>
+The buffer read uses a fixed (not incrementing) address.<p>
+<em>block_size</em> <em>must</em> be set to the value writted into <em>func's</em> I/O block size FBR register.<p>
+If <em>len</em> <em>block_size</em> == 0, a block mode transfer is used; a byte mode transfer is used if <em>len</em> &lt; <em>block_size</em>.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer to store the data read. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of data to read. </td></tr>
+ <tr><td valign=top><em>block_size</em>&nbsp;</td><td>block size to use for this transfer.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga16" doxytag="libsdio.h::sdio_read8" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_read8 </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read an 8 bit register.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>the data read.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga20" doxytag="libsdio.h::sdio_read8_async" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_read8_async </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap><a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>callback</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>arg</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read an 8 bit register, without waiting for completion.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>the data read. </td></tr>
+ <tr><td valign=top><em>callback</em>&nbsp;</td><td>function to be called when the read completes. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>argument to be passed to callback.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga22" doxytag="libsdio.h::sdio_read_async" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_read_async </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>size_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>len</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>block_size</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap><a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>callback</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>arg</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Read a buffer from a 8 bit wide register/FIFO, without waiting for completion.<p>
+The buffer read uses a fixed (not incrementing) address.<p>
+<em>block_size</em> <em>must</em> be set to the value writted into <em>func's</em> I/O block size FBR register.<p>
+If <em>len</em> <em>block_size</em> == 0, a block mode transfer is used; a byte mode transfer is used if <em>len</em> &lt; <em>block_size</em>.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer to store the data read. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of data to read. </td></tr>
+ <tr><td valign=top><em>block_size</em>&nbsp;</td><td>block size to use for this transfer. </td></tr>
+ <tr><td valign=top><em>callback</em>&nbsp;</td><td>function to be called when the read completes. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>argument to be passed to callback.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga24" doxytag="libsdio.h::sdio_reinsert_card" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_reinsert_card </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>uif</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Force a card removal and reinsertion.<p>
+This will power cycle the card if the slot hardware supports power control.<p>
+<dl compact><dt><b>Note:</b></dt><dd>The device handle will no longer be valid.</dd></dl>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga15" doxytag="libsdio.h::sdio_set_block_size" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_set_block_size </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>blksz</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set a function's block size.<p>
+The function's block size registers will be written if necessary.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>function to modify. </td></tr>
+ <tr><td valign=top><em>blksz</em>&nbsp;</td><td>the new block size; or 0 for the default size.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga8" doxytag="libsdio.h::sdio_set_bus_width" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_set_bus_width </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>bus_width</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set an SDIO bus to 1 bit or 4 bit wide mode.<p>
+The CCCR bus interface control register will be read and rewritten with the new bus width.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>bus_width</em>&nbsp;</td><td>bus width (1 or 4).</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error with errno set.</dd></dl>
+<dl compact><dt><b>Note:</b></dt><dd>The card capabilities are <em>not</em> checked. The user should ensure 4 bit mode is not enabled on a card that does not support it. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga9" doxytag="libsdio.h::sdio_set_max_bus_freq" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_set_max_bus_freq </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>max_freq</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Limit the frequency of (or stop) the SD bus clock.<p>
+The frequency cannot be set greater than that supported by the card or the controller.<p>
+<dl compact><dt><b>Note:</b></dt><dd>Stopping the bus clock while other device drivers are executing commands may result in those commands not completing until the bus clock is restarted.</dd></dl>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>max_freq</em>&nbsp;</td><td>maximum frequency (Hz) or 0 to stop the bus clock until the start of the next command. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga12" doxytag="libsdio.h::sdio_std_if" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint8_t sdio_std_if </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Return the standard interface code for a function.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function to query.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>the standard interface. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga19" doxytag="libsdio.h::sdio_write" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_write </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>size_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>len</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>block_size</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write a buffer to an 8 bit wide register/FIFO.<p>
+The buffer write uses a fixed (not incrementing) address.<p>
+<em>block_size</em> <em>must</em> be set to the value writted into <em>func's</em> I/O block size FBR register.<p>
+If <em>len</em> <em>block_size</em> == 0, a block mode transfer is used; a byte mode transfer is used if <em>len</em> &lt; <em>block_size</em>.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer of data to write. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of the data to write. </td></tr>
+ <tr><td valign=top><em>block_size</em>&nbsp;</td><td>block size to use for this transfer.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga17" doxytag="libsdio.h::sdio_write8" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_write8 </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write an 8 bit register.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>the data to write.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga21" doxytag="libsdio.h::sdio_write8_async" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_write8_async </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint8_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap><a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>callback</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>arg</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write an 8 bit register, without waiting for completion.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>the data to write. </td></tr>
+ <tr><td valign=top><em>callback</em>&nbsp;</td><td>function to be called when the write completes. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>argument to be passed to callback.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga23" doxytag="libsdio.h::sdio_write_async" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_write_async </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top"><a class="el" href="group__libsdio.html#ga0">sdio_uif_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>uif</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>func</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>uint32_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>addr</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>const uint8_t *&nbsp;</td>
+ <td class="mdname" nowrap> <em>data</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>size_t&nbsp;</td>
+ <td class="mdname" nowrap> <em>len</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>int&nbsp;</td>
+ <td class="mdname" nowrap> <em>block_size</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap><a class="el" href="group__libsdio.html#ga2">sdio_io_callback_t</a>&nbsp;</td>
+ <td class="mdname" nowrap> <em>callback</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>void *&nbsp;</td>
+ <td class="mdname" nowrap> <em>arg</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Write a buffer to an 8 bit wide register/FIFO, without waiting for completion.<p>
+The buffer write uses a fixed (not incrementing) address.<p>
+<em>block_size</em> <em>must</em> be set to the value writted into <em>func's</em> I/O block size FBR register.<p>
+If <em>len</em> <em>block_size</em> == 0, a block mode transfer is used; a byte mode transfer is used if <em>len</em> &lt; <em>block_size</em>.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>uif</em>&nbsp;</td><td>device handle. </td></tr>
+ <tr><td valign=top><em>func</em>&nbsp;</td><td>card function. </td></tr>
+ <tr><td valign=top><em>addr</em>&nbsp;</td><td>register/FIFO address. </td></tr>
+ <tr><td valign=top><em>data</em>&nbsp;</td><td>buffer of data to write. </td></tr>
+ <tr><td valign=top><em>len</em>&nbsp;</td><td>length of the data to write. </td></tr>
+ <tr><td valign=top><em>block_size</em>&nbsp;</td><td>block size to use for this transfer. </td></tr>
+ <tr><td valign=top><em>callback</em>&nbsp;</td><td>function to be called when the write completes. </td></tr>
+ <tr><td valign=top><em>arg</em>&nbsp;</td><td>argument to be passed to callback.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; or -ve on error with errno set. </dd></dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/group__registers.html b/unifi_hostsw_linux_147/sdioemb/html/group__registers.html
new file mode 100644
index 0000000..12229c1
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/group__registers.html
@@ -0,0 +1,257 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: CSR specific SDIO registers</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>CSR specific SDIO registers</h1><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Defines</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga0">SDIO_CSR_SLEEP_STATE</a>&nbsp;&nbsp;&nbsp;0xf0</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga1" doxytag="registers::SDIO_CSR_SLEEP_STATE_FUNC" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>SDIO_CSR_SLEEP_STATE_FUNC</b>(f)&nbsp;&nbsp;&nbsp;((f) &lt;&lt; 4)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga2" doxytag="registers::SDIO_CSR_SLEEP_STATE_RDY_INT_EN" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>SDIO_CSR_SLEEP_STATE_RDY_INT_EN</b>&nbsp;&nbsp;&nbsp;0x02</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga3" doxytag="registers::SDIO_CSR_SLEEP_STATE_WAKE_REQ" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>SDIO_CSR_SLEEP_STATE_WAKE_REQ</b>&nbsp;&nbsp;&nbsp;0x01</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga4">SDIO_CSR_HOST_INT</a>&nbsp;&nbsp;&nbsp;0xf1</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga5" doxytag="registers::SDIO_CSR_HOST_INT_CL" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>SDIO_CSR_HOST_INT_CL</b>&nbsp;&nbsp;&nbsp;0x01</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga6">SDIO_CSR_FROM_HOST_SCRATCH0</a>&nbsp;&nbsp;&nbsp;0xf2</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga7">SDIO_CSR_FROM_HOST_SCRATCH1</a>&nbsp;&nbsp;&nbsp;0xf3</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga8">SDIO_CSR_TO_HOST_SCRATCH0</a>&nbsp;&nbsp;&nbsp;0xf4</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga9">SDIO_CSR_TO_HOST_SCRATCH1</a>&nbsp;&nbsp;&nbsp;0xf5</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga10">SDIO_CSR_EXT_IO_EN</a>&nbsp;&nbsp;&nbsp;0xf6</td></tr>
+
+<tr><td colspan=2><br><h2>Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>enum &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__registers.html#ga11">sdio_sleep_state</a> { <br>
+&nbsp;&nbsp;<b>SLEEP_STATE_AWAKE</b> = SDIO_CSR_SLEEP_STATE_WAKE_REQ,
+<br>
+&nbsp;&nbsp;<b>SLEEP_STATE_DROWSY</b> = SDIO_CSR_SLEEP_STATE_WAKE_REQ | SDIO_CSR_SLEEP_STATE_RDY_INT_EN,
+<br>
+&nbsp;&nbsp;<b>SLEEP_STATE_TORPID</b> = 0x00
+<br>
+ }</td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+Registers at 0xF0 - 0xFF in the CCCR are reserved for vendor specific registers. The registers documented here are specific to following CSR chips:<p>
+<ul>
+<li>BlueCore (6 and later)</li><li>UltraCore </li></ul>
+<hr><h2>Define Documentation</h2>
+<a class="anchor" name="ga10" doxytag="sdio_csr.h::SDIO_CSR_EXT_IO_EN" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDIO_CSR_EXT_IO_EN&nbsp;&nbsp;&nbsp;0xf6
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Extended I/O enable.<p>
+Similar to the standard CCCR I/O Enable register, this is used to detect if an internal reset of a function has occured and (optionally) reenable it.<p>
+An internal reset is detected by CCCR I/O Enable bit being set and the corresponding EXT_IO_EN bit being clear. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga6" doxytag="sdio_csr.h::SDIO_CSR_FROM_HOST_SCRATCH0" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDIO_CSR_FROM_HOST_SCRATCH0&nbsp;&nbsp;&nbsp;0xf2
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+From host scratch register 0.<p>
+A read/write register that can be used for signalling between the host and the chip.<p>
+The usage of this register depends on the version of the chip or firmware. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga7" doxytag="sdio_csr.h::SDIO_CSR_FROM_HOST_SCRATCH1" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDIO_CSR_FROM_HOST_SCRATCH1&nbsp;&nbsp;&nbsp;0xf3
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+From host scratch register 1.<p>
+<dl compact><dt><b>See also:</b></dt><dd><a class="el" href="group__registers.html#ga6">SDIO_CSR_FROM_HOST_SCRATCH0</a> </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="sdio_csr.h::SDIO_CSR_HOST_INT" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDIO_CSR_HOST_INT&nbsp;&nbsp;&nbsp;0xf1
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Host interrupt clear register.<p>
+Writing a 1 to bit 0 clears an SDIO interrupt raised by a generic function. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga0" doxytag="sdio_csr.h::SDIO_CSR_SLEEP_STATE" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDIO_CSR_SLEEP_STATE&nbsp;&nbsp;&nbsp;0xf0
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Interrupt status/host wakeup register.<p>
+This controls a function's deep sleep state.<p>
+<dl compact><dt><b>See also:</b></dt><dd>enum <a class="el" href="group__registers.html#ga11">sdio_sleep_state</a> </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga8" doxytag="sdio_csr.h::SDIO_CSR_TO_HOST_SCRATCH0" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDIO_CSR_TO_HOST_SCRATCH0&nbsp;&nbsp;&nbsp;0xf4
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+To host scratch register 0.<p>
+A read only register that may be used for signalling between the chip and the host.<p>
+The usage of this register depends on the version of the chip or firmware. </td>
+ </tr>
+</table>
+<a class="anchor" name="ga9" doxytag="sdio_csr.h::SDIO_CSR_TO_HOST_SCRATCH1" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define SDIO_CSR_TO_HOST_SCRATCH1&nbsp;&nbsp;&nbsp;0xf5
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+To host scratch register 1.<p>
+<dl compact><dt><b>See also:</b></dt><dd><a class="el" href="group__registers.html#ga8">SDIO_CSR_TO_HOST_SCRATCH0</a> </dd></dl>
+ </td>
+ </tr>
+</table>
+<hr><h2>Enumeration Type Documentation</h2>
+<a class="anchor" name="ga11" doxytag="sdio_csr.h::sdio_sleep_state" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> enum <a class="el" href="group__registers.html#ga11">sdio_sleep_state</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Deep sleep states as set via the sleep state register.<p>
+These states are used to control when the chip may go into a deep sleep (a low power mode).<p>
+Since a chip in deep sleep may not respond to SDIO commands, the host should ensure that the chip is not in deep sleep before attempting SDIO commands to functions 1 to 7.<p>
+The available states are:<p>
+AWAKE - chip must not enter deep sleep and should exit deep sleep if it's currently sleeping.<p>
+TORPID - chip may enter deep sleep.<p>
+DROWSY - a transition state between TORPID and AWAKE. This is AWAKE plus the chip asserts an interrupt when the chip is awake.<p>
+<dl compact><dt><b>See also:</b></dt><dd><a class="el" href="group__registers.html#ga0">SDIO_CSR_SLEEP_STATE</a> </dd></dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/group__sdriver.html b/unifi_hostsw_linux_147/sdioemb/html/group__sdriver.html
new file mode 100644
index 0000000..6451acf
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/group__sdriver.html
@@ -0,0 +1,574 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: SDIO slot driver API</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>SDIO slot driver API</h1>The SDIO slot driver API provides an interface for the SDIO layer to driver an SDIO slot (socket).
+<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Structures</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>struct &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html">sdio_slot</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>struct &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structslot__caps.html">slot_caps</a></td></tr>
+
+<tr><td colspan=2><br><h2>Defines</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga10" doxytag="sdriver::CSPI_FUNC" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_FUNC</b>(f)&nbsp;&nbsp;&nbsp;(f)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga11" doxytag="sdriver::CSPI_READ" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_READ</b>&nbsp;&nbsp;&nbsp;0x10</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga12" doxytag="sdriver::CSPI_WRITE" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_WRITE</b>&nbsp;&nbsp;&nbsp;0x20</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga13" doxytag="sdriver::CSPI_BURST" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_BURST</b>&nbsp;&nbsp;&nbsp;0x40</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga14" doxytag="sdriver::CSPI_TYPE_MASK" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_TYPE_MASK</b>&nbsp;&nbsp;&nbsp;0x70</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga15">CSPI_MODE</a>&nbsp;&nbsp;&nbsp;0xf7</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga16" doxytag="sdriver::CSPI_MODE_PADDED_WRITE_HDRS" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_MODE_PADDED_WRITE_HDRS</b>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 7)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga17" doxytag="sdriver::CSPI_MODE_PADDED_READ_HDRS" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_MODE_PADDED_READ_HDRS</b>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 6)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>#define&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga18">CSPI_MODE_BE_REG</a>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 5)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga19" doxytag="sdriver::CSPI_MODE_BE_BURST" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_MODE_BE_BURST</b>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 4)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga20" doxytag="sdriver::CSPI_MODE_INT_ACTIVE_HIGH" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_MODE_INT_ACTIVE_HIGH</b>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 3)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga21" doxytag="sdriver::CSPI_MODE_INT_ON_ERR" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_MODE_INT_ON_ERR</b>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 2)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga22" doxytag="sdriver::CSPI_MODE_LEN_FIELD_PRESENT" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_MODE_LEN_FIELD_PRESENT</b>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 1)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga23" doxytag="sdriver::CSPI_MODE_DRV_MISO_ON_RISING_CLK" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_MODE_DRV_MISO_ON_RISING_CLK</b>&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 0)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga24" doxytag="sdriver::CSPI_STATUS" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_STATUS</b>&nbsp;&nbsp;&nbsp;0xf8</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga25" doxytag="sdriver::CSPI_PADDING" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_PADDING</b>&nbsp;&nbsp;&nbsp;0xf9</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga26" doxytag="sdriver::CSPI_PADDING_REG" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_PADDING_REG</b>(p)&nbsp;&nbsp;&nbsp;((p) &lt;&lt; 0)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga27" doxytag="sdriver::CSPI_PADDING_BURST" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_PADDING_BURST</b>(p)&nbsp;&nbsp;&nbsp;((p) &lt;&lt; 4)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga28" doxytag="sdriver::CSPI_PADDING_MAX" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_PADDING_MAX</b>&nbsp;&nbsp;&nbsp;15</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga29" doxytag="sdriver::CSPI_PADDING_REG_DFLT" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_PADDING_REG_DFLT</b>&nbsp;&nbsp;&nbsp;0</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga30" doxytag="sdriver::CSPI_PADDING_BURST_DFLT" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_PADDING_BURST_DFLT</b>&nbsp;&nbsp;&nbsp;2</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="ga31" doxytag="sdriver::CSPI_REG_TRANSFER_LEN" ></a>
+#define&nbsp;</td><td class="memItemRight" valign=bottom><b>CSPI_REG_TRANSFER_LEN</b>&nbsp;&nbsp;&nbsp;(1 + 3 + CSPI_PADDING_MAX + 1 + 2)</td></tr>
+
+<tr><td colspan=2><br><h2>Enumerations</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>enum &nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga32">sdio_power</a> { <br>
+&nbsp;&nbsp;<a class="el" href="group__sdriver.html#gga32a3">SDIO_POWER_OFF</a> = 0,
+<br>
+&nbsp;&nbsp;<a class="el" href="group__sdriver.html#gga32a4">SDIO_POWER_3V3</a> = 33
+<br>
+ }</td></tr>
+
+<tr><td colspan=2><br><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga0">sdio_card_inserted</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga1">sdio_card_removed</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga2">sdio_cmd_complete</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *cmd)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga3">sdio_interrupt</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga4">sdio_suspend</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga5">sdio_resume</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga6">sdio_slot_alloc</a> (size_t drv_data_size)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga7">sdio_slot_free</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga8">sdio_slot_register</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="group__sdriver.html#ga9">sdio_slot_unregister</a> (struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+The SDIO slot driver API provides an interface for the SDIO layer to driver an SDIO slot (socket).
+<p>
+Slot drivers register with the SDIO layer (<a class="el" href="group__sdriver.html#ga10">sdio_slot_register()</a>), providing functions to starting commands, enabling/disable card interrupts, card detection and bus power control.<p>
+Functions are provided to notify the SDIO layer when a command has completed (<a class="el" href="group__sdriver.html#ga15">sdio_cmd_complete()</a>) and when an SDIO card interrupt has occurred (<a class="el" href="group__sdriver.html#ga14">sdio_interrupt()</a>). <hr><h2>Define Documentation</h2>
+<a class="anchor" name="ga15" doxytag="cspi.h::CSPI_MODE" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define CSPI_MODE&nbsp;&nbsp;&nbsp;0xf7
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+CSPI_MODE function 0 register.<p>
+Various CSPI mode settings.<p>
+<dl compact><dt><b>See also:</b></dt><dd>CSPI specification (CS-110124-SP) </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga18" doxytag="cspi.h::CSPI_MODE_BE_REG" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> #define CSPI_MODE_BE_REG&nbsp;&nbsp;&nbsp;(1 &lt;&lt; 5)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+BigEndianRegisters bit of <a class="el" href="group__sdriver.html#ga15">CSPI_MODE</a> -- enable big-endian CSPI register reads and writes.<p>
+<dl compact><dt><b>Warning:</b></dt><dd>This bit should never be set as it's not possible to use this mode without knowledge of which registers are 8 bit and which are 16 bit. </dd></dl>
+ </td>
+ </tr>
+</table>
+<hr><h2>Enumeration Type Documentation</h2>
+<a class="anchor" name="ga32" doxytag="slot_api.h::sdio_power" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> enum <a class="el" href="group__sdriver.html#ga32">sdio_power</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Valid SDIO bus voltage levels. <dl compact><dt><b>Enumeration values: </b></dt><dd>
+<table border=0 cellspacing=2 cellpadding=0>
+<tr><td valign=top><em><a class="anchor" name="gga32a3" doxytag="SDIO_POWER_OFF" ></a>SDIO_POWER_OFF</em>&nbsp;</td><td>
+Power switched off. </td></tr>
+<tr><td valign=top><em><a class="anchor" name="gga32a4" doxytag="SDIO_POWER_3V3" ></a>SDIO_POWER_3V3</em>&nbsp;</td><td>
+Voltage set to 3.3V. </td></tr>
+</table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr><h2>Function Documentation</h2>
+<a class="anchor" name="ga0" doxytag="sdio_card.c::sdio_card_inserted" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_card_inserted </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Notify the SDIO layer that a card has been inserted.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot for the inserted card. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="sdio_card.c::sdio_card_removed" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_card_removed </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Notify the SDIO layer that a card has been removed<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot for the removed card. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="sdio_cmd.c::sdio_cmd_complete" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_cmd_complete </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>slot</em>, </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td></td>
+ <td class="md" nowrap>struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *&nbsp;</td>
+ <td class="mdname" nowrap> <em>cmd</em></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="md">)&nbsp;</td>
+ <td class="md" colspan="2"></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Notify the SDIO layer that an SDIO commmand has completed.<p>
+Slot drivers should set the <em>cmd's</em> status and response and call this when a command has completed (either successfully or not).<p>
+Callable from: interrupt context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot which completed the command. </td></tr>
+ <tr><td valign=top><em>cmd</em>&nbsp;</td><td>the completed command. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="sdio_int.c::sdio_interrupt" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_interrupt </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Notify the SDIO layer that the card interrupt is asserted.<p>
+Callable from: interrupt context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot with the asserted interrupt. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga5" doxytag="sdio_pm.c::sdio_resume" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_resume </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Notify the SDIO driver that the resume event has been received.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot being resumed. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga6" doxytag="sdio_slot.c::sdio_slot_alloc" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structsdio__slot.html">sdio_slot</a>* sdio_slot_alloc </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">size_t&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>drv_data_size</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Allocate and initialize and SDIO slot driver structure.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>drv_data_size</em>&nbsp;</td><td>size of slot driver's drv_data.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>the allocated structure; or NULL if no memory could be allocated. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga7" doxytag="sdio_slot.c::sdio_slot_free" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_slot_free </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Free a slot_driver allocated with <a class="el" href="group__sdriver.html#ga8">sdio_slot_alloc()</a>.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot driver to free. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga8" doxytag="sdio_slot.c::sdio_slot_register" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int sdio_slot_register </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Register a slot driver with the SDIO layer.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot driver to register.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error: -ENOMEM - maximum number of slots are already registered.</dd></dl>
+<dl compact><dt><b>See also:</b></dt><dd><a class="el" href="group__config.html#ga0">SDD_SLOTS_MAX</a> </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga9" doxytag="sdio_slot.c::sdio_slot_unregister" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_slot_unregister </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Unregister a slot driver from the SDIO layer.<p>
+Callable from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot driver to unregister. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="sdio_pm.c::sdio_suspend" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void sdio_suspend </td>
+ <td class="md" valign="top">(&nbsp;</td>
+ <td class="md" nowrap valign="top">struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *&nbsp;</td>
+ <td class="mdname1" valign="top" nowrap> <em>slot</em> </td>
+ <td class="md" valign="top">&nbsp;)&nbsp;</td>
+ <td class="md" nowrap></td>
+ </tr>
+
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Notify the SDIO driver that the suspend event has been received.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot being suspended. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/index.html b/unifi_hostsw_linux_147/sdioemb/html/index.html
new file mode 100644
index 0000000..61bdc91
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/index.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Main Page</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindexHL" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdioemb Documentation</h1>
+<p>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/libsdio_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/libsdio_8h-source.html
new file mode 100644
index 0000000..972ccb5
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/libsdio_8h-source.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/libsdio.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/libsdio.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * SDIO Userspace Interface library.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef SDIOEMB_LIBSDIO_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define SDIOEMB_LIBSDIO_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include &lt;stdint.h&gt;</span>
+00013
+00028
+00029 <span class="preprocessor">#ifdef __cplusplus</span>
+00030 <span class="preprocessor"></span><span class="keyword">extern</span> <span class="stringliteral">"C"</span> {
+00031 <span class="preprocessor">#endif</span>
+00032 <span class="preprocessor"></span>
+00033 <span class="keyword">struct </span>sdio_uif;
+00034
+<a name="l00038"></a><a class="code" href="group__libsdio.html#ga0">00038</a> <span class="keyword">typedef</span> <span class="keyword">struct </span>sdio_uif *<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a>;
+00039
+<a name="l00046"></a><a class="code" href="group__libsdio.html#ga1">00046</a> <span class="keyword">typedef</span> void (*<a class="code" href="group__libsdio.html#ga1">sdio_int_handler_t</a>)(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">void</span> *arg);
+00047
+<a name="l00056"></a><a class="code" href="group__libsdio.html#ga2">00056</a> <span class="keyword">typedef</span> void (*<a class="code" href="group__libsdio.html#ga2">sdio_io_callback_t</a>)(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">void</span> *arg, <span class="keywordtype">int</span> status);
+00057
+00074 <a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> <a class="code" href="group__libsdio.html#ga3">sdio_open</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *dev_filename,
+00075 <a class="code" href="group__libsdio.html#ga1">sdio_int_handler_t</a> int_handler, <span class="keywordtype">void</span> *arg);
+00076
+00089 <span class="keywordtype">void</span> <a class="code" href="group__libsdio.html#ga17">sdio_interrupt_mask</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00090
+00099 <span class="keywordtype">void</span> <a class="code" href="group__libsdio.html#ga18">sdio_interrupt_unmask</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00100
+00107 <span class="keywordtype">void</span> <a class="code" href="group__libsdio.html#ga2">sdio_close</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00108
+00116 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga3">sdio_num_functions</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00117
+00133 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga14">sdio_set_bus_width</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> bus_width);
+00134
+00149 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga13">sdio_set_max_bus_freq</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> max_freq);
+00150
+00158 uint16_t <a class="code" href="group__libsdio.html#ga6">sdio_manf_id</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00159
+00167 uint16_t <a class="code" href="group__libsdio.html#ga7">sdio_card_id</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00168
+00177 uint8_t <a class="code" href="group__libsdio.html#ga8">sdio_std_if</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func);
+00178
+00187 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga9">sdio_max_block_size</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func);
+00188
+00200 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga10">sdio_block_size</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func);
+00201
+00213 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga11">sdio_set_block_size</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, <span class="keywordtype">int</span> blksz);
+00214
+00225 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga17">sdio_read8</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data);
+00226
+00237 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga18">sdio_write8</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t data);
+00238
+00259 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga21">sdio_read</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data,
+00260 size_t len, <span class="keywordtype">int</span> block_size);
+00261
+00282 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga22">sdio_write</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, <span class="keyword">const</span> uint8_t *data,
+00283 size_t len, <span class="keywordtype">int</span> block_size);
+00284
+00297 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga5">sdio_read8_async</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data,
+00298 <a class="code" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, <span class="keywordtype">void</span> *arg);
+00299
+00312 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga6">sdio_write8_async</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t data,
+00313 <a class="code" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, <span class="keywordtype">void</span> *arg);
+00314
+00338 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga7">sdio_read_async</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data,
+00339 size_t len, <span class="keywordtype">int</span> block_size,
+00340 <a class="code" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, <span class="keywordtype">void</span> *arg);
+00341
+00365 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga8">sdio_write_async</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">int</span> func, uint32_t addr, <span class="keyword">const</span> uint8_t *data,
+00366 size_t len, <span class="keywordtype">int</span> block_size,
+00367 <a class="code" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback, <span class="keywordtype">void</span> *arg);
+00380 <span class="keywordtype">int</span> <a class="code" href="group__libsdio.html#ga16">sdio_reinsert_card</a>(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00381
+00382 <span class="preprocessor">#ifdef __cplusplus</span>
+00383 <span class="preprocessor"></span>} <span class="comment">/* extern "C" */</span>
+00384 <span class="preprocessor">#endif</span>
+00385 <span class="preprocessor"></span>
+00388 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef SDIOEMB_LIBSDIO_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/libsdio__internal_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/libsdio__internal_8h-source.html
new file mode 100644
index 0000000..9bce9b8
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/libsdio__internal_8h-source.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/libsdio/libsdio_internal.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/libsdio/libsdio_internal.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * libsdio internal header.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2008 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef LIBSDIO_INTERNAL_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define LIBSDIO_INTERNAL_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="keyword">struct </span>cmd_queue_elem {
+00013 <span class="keyword">struct </span>cmd_queue_elem *next;
+00014 <a class="code" href="group__libsdio.html#ga2">sdio_io_callback_t</a> callback;
+00015 <span class="keywordtype">void</span> *arg;
+00016 <span class="keyword">struct </span>sdio_uif_cmd cmd;
+00017 uint8_t write8_data;
+00018 };
+00019
+00020 <span class="keyword">struct </span>cmd_queue {
+00021 <span class="keyword">struct </span>cmd_queue_elem *head;
+00022 <span class="keyword">struct </span>cmd_queue_elem *tail;
+00023 pthread_cond_t cond;
+00024 };
+00025
+00026 <span class="keyword">struct </span>sdio_uif {
+00027 void (*int_handler)(<span class="keyword">struct </span>sdio_uif *, <span class="keywordtype">void</span> *);
+00028 <span class="keywordtype">void</span> *arg;
+00029 <span class="keywordtype">int</span> fd;
+00030 pthread_t int_thread;
+00031 pthread_mutex_t mutex;
+00032 pthread_cond_t int_cond;
+00033 <span class="keywordtype">int</span> int_masked;
+00034
+00035 <span class="keyword">struct </span>cmd_queue cmd_queue;
+00036 pthread_t async_thread;
+00037 };
+00038
+00039 <span class="keywordtype">int</span> async_thread_start(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00040 <span class="keywordtype">void</span> async_thread_stop(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif);
+00041
+00042 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef LIBSDIO_INTERNAL_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/modules.html b/unifi_hostsw_linux_147/sdioemb/html/modules.html
new file mode 100644
index 0000000..6e260ca
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/modules.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Module Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindexHL" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdioemb Modules</h1>Here is a list of all modules:<ul>
+<li><a class="el" href="group__libsdio.html">Userspace SDIO library (libsdio)</a>
+<li><a class="el" href="group__fdriver.html">SDIO function driver API</a>
+<li><a class="el" href="group__registers.html">CSR specific SDIO registers</a>
+<li><a class="el" href="group__sdriver.html">SDIO slot driver API</a>
+<li><a class="el" href="group__config.html">Compile-time configuration</a>
+</ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/pages.html b/unifi_hostsw_linux_147/sdioemb/html/pages.html
new file mode 100644
index 0000000..979ce05
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/pages.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: Page Index</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindexHL" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdioemb Related Pages</h1>Here is a list of all related documentation pages:<ul>
+<li><a class="el" href="deprecated.html">Deprecated List</a>
+
+<li><a class="el" href="bug.html">Bug List</a>
+
+</ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdd__test_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdd__test_8h-source.html
new file mode 100644
index 0000000..79fdbdc
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdd__test_8h-source.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/tests/sdd_test.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/tests/sdd_test.h</h1><div class="fragment"><pre>00001 <span class="preprocessor">#ifndef LIBSDIO_TEST_H</span>
+00002 <span class="preprocessor"></span><span class="preprocessor">#define LIBSDIO_TEST_H</span>
+00003 <span class="preprocessor"></span>
+00004 <span class="preprocessor">#ifdef __cplusplus</span>
+00005 <span class="preprocessor"></span><span class="keyword">extern</span> <span class="stringliteral">"C"</span> {
+00006 <span class="preprocessor">#endif</span>
+00007 <span class="preprocessor"></span>
+00008 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
+00009
+00010 <span class="preprocessor">#include &lt;sdioemb/libsdio.h&gt;</span>
+00011 <span class="preprocessor">#include &lt;sdioemb/sdio.h&gt;</span>
+00012 <span class="preprocessor">#include &lt;sdioemb/sdio_csr.h&gt;</span>
+00013
+00014 <span class="keyword">struct </span>sdd_test_card {
+00015 uint16_t manf_id;
+00016 uint16_t card_id;
+00017 <span class="keyword">const</span> <span class="keywordtype">char</span> *name;
+00018 <span class="keywordtype">void</span> *card_data;
+00019 };
+00020
+00021 <span class="keyword">typedef</span> void (*sdd_test_func_t)(<a class="code" href="group__libsdio.html#ga0">sdio_uif_t</a> uif, <span class="keywordtype">void</span> *arg);
+00022
+00023 <span class="keywordtype">int</span> sdd_test_run(<span class="keyword">const</span> <span class="keywordtype">char</span> *test, <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[],
+00024 sdd_test_func_t test_func, <span class="keywordtype">void</span> *test_arg,
+00025 <a class="code" href="group__libsdio.html#ga1">sdio_int_handler_t</a> int_handler, <span class="keywordtype">void</span> *int_arg);
+00026
+00027 <span class="keywordtype">void</span> *sdd_test_check_cards(<span class="keyword">const</span> <span class="keyword">struct</span> sdd_test_card *cards);
+00028
+00029 <span class="keywordtype">void</span> sdd_test_pass(<span class="keywordtype">void</span>);
+00030 <span class="keywordtype">void</span> sdd_test_fail(<span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, ...);
+00031 <span class="keywordtype">void</span> sdd_test_abort(<span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, ...);
+00032
+00033 <span class="keywordtype">int</span> sdd_test_max_iters(<span class="keywordtype">void</span>);
+00034
+00035 <span class="preprocessor">#ifdef __cplusplus</span>
+00036 <span class="preprocessor"></span>} <span class="comment">/* extern "C" */</span>
+00037 <span class="preprocessor">#endif</span>
+00038 <span class="preprocessor"></span>
+00039 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef LIBSDIO_TEST_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio_8h-source.html
new file mode 100644
index 0000000..7ae305f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio_8h-source.html
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Standard SDIO definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef SDIOEMB_SDIO_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define SDIOEMB_SDIO_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="comment">/* Maximum time for VDD to rise to VDD min. */</span>
+00013 <span class="preprocessor">#define SDIO_POWER_UP_TIME_MS 250</span>
+00014 <span class="preprocessor"></span>
+00015 <span class="comment">/* Minimum SD bus clock a card must support (Hz). */</span>
+00016 <span class="preprocessor">#define SDIO_CLOCK_FREQ_MIN 400000</span>
+00017 <span class="preprocessor"></span>
+00018 <span class="comment">/* Maximum clock frequency for normal mode (Hz).</span>
+00019 <span class="comment"> * </span>
+00020 <span class="comment"> * Although high speed mode should be suitable for all speeds not all</span>
+00021 <span class="comment"> * controller/card combinations are capable of meeting the higher</span>
+00022 <span class="comment"> * tolerances for (e.g.) clock rise/fall times. Therefore, default</span>
+00023 <span class="comment"> * mode is used where possible for improved compatibility. */</span>
+00024 <span class="preprocessor">#define SDIO_CLOCK_FREQ_NORMAL_SPD 25000000</span>
+00025 <span class="preprocessor"></span>
+00026 <span class="comment">/* Maximum clock frequency for high speed mode (Hz). */</span>
+00027 <span class="preprocessor">#define SDIO_CLOCK_FREQ_HIGH_SPD 50000000</span>
+00028 <span class="preprocessor"></span>
+00029 <span class="preprocessor">#define SDIO_MAX_FUNCTIONS 8 </span><span class="comment">/* incl. F0 */</span>
+00030
+00031 <span class="comment">/* Command argument format. */</span>
+00032
+00033 <span class="preprocessor">#define SDIO_CMD52_ARG_WRITE 0x80000000</span>
+00034 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CMD52_ARG_FUNC(f) ((f) &lt;&lt; 28)</span>
+00035 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CMD52_ARG_ADDR(a) ((a) &lt;&lt; 9)</span>
+00036 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CMD52_ARG_DATA(d) ((d) &lt;&lt; 0)</span>
+00037 <span class="preprocessor"></span>
+00038 <span class="preprocessor">#define SDIO_CMD53_ARG_WRITE 0x80000000</span>
+00039 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CMD53_ARG_FUNC(f) ((f) &lt;&lt; 28)</span>
+00040 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CMD53_ARG_BLK_MODE 0x08000000</span>
+00041 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CMD53_ARG_ADDR(a) ((a) &lt;&lt; 9)</span>
+00042 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CMD53_ARG_CNT(c) ((c) &lt;&lt; 0)</span>
+00043 <span class="preprocessor"></span>
+00044 <span class="comment">/* Response format. */</span>
+00045
+00046 <span class="preprocessor">#define SDIO_R5_DATA(r) (((r) &gt;&gt; 0) &amp; 0xff)</span>
+00047 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_R5_OUT_OF_RANGE (1 &lt;&lt; 8)</span>
+00048 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_R5_FUNCTION_NUMBER (1 &lt;&lt; 9)</span>
+00049 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_R5_ERROR (1 &lt;&lt; 11)</span>
+00050 <span class="preprocessor"></span>
+00051 <span class="comment">/* Register offsets and bits. */</span>
+00052
+00053 <span class="preprocessor">#define SDIO_OCR_CARD_READY 0x80000000</span>
+00054 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_OCR_NUM_FUNCS_MASK 0x70000000</span>
+00055 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_OCR_NUM_FUNCS_OFFSET 28</span>
+00056 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_OCR_VOLTAGE_3V3 0x00300000 </span><span class="comment">/* 3.2-3.3V &amp; 3.3-3.4V */</span>
+00057
+00058 <span class="preprocessor">#define SDIO_CCCR_SDIO_REV 0x00</span>
+00059 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_SD_REV 0x01</span>
+00060 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_IO_EN 0x02</span>
+00061 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_IO_READY 0x03</span>
+00062 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_INT_EN 0x04</span>
+00063 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_INT_EN_MIE 0x01</span>
+00064 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_INT_PENDING 0x05</span>
+00065 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_IO_ABORT 0x06</span>
+00066 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_BUS_IFACE_CNTL 0x07</span>
+00067 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_BUS_IFACE_CNTL_CD_R_DISABLE 0x80</span>
+00068 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_BUS_IFACE_CNTL_ECSI 0x20</span>
+00069 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_BUS_IFACE_CNTL_4BIT_BUS 0x02</span>
+00070 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_CARD_CAPS 0x08</span>
+00071 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_CARD_CAPS_LSC 0x40</span>
+00072 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_CARD_CAPS_4BLS 0x80</span>
+00073 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_CIS_PTR 0x09</span>
+00074 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_BUS_SUSPEND 0x0c</span>
+00075 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_FUNC_SEL 0x0d</span>
+00076 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_EXEC_FLAGS 0x0e</span>
+00077 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_READY_FLAGS 0x0f</span>
+00078 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_F0_BLK_SIZE 0x10</span>
+00079 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_PWR_CNTL 0x12</span>
+00080 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CCCR_HIGH_SPEED 0x13</span>
+00081 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_HIGH_SPEED_SHS 0x01</span>
+00082 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CCCR_HIGH_SPEED_EHS 0x02</span>
+00083 <span class="preprocessor"></span>
+00084 <span class="preprocessor">#define SDIO_FBR_REG(f, r) (0x100*(f) + (r))</span>
+00085 <span class="preprocessor"></span>
+00086 <span class="preprocessor">#define SDIO_FBR_STD_IFACE(f) SDIO_FBR_REG(f, 0x00)</span>
+00087 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_FBR_STD_IFACE_EXT(f) SDIO_FBR_REG(f, 0x01)</span>
+00088 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_FBR_CIS_PTR(f) SDIO_FBR_REG(f, 0x09)</span>
+00089 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_FBR_CSA_PTR(f) SDIO_FBR_REG(f, 0x0c)</span>
+00090 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_FBR_CSA_DATA(f) SDIO_FBR_REG(f, 0x0f)</span>
+00091 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_FBR_BLK_SIZE(f) SDIO_FBR_REG(f, 0x10)</span>
+00092 <span class="preprocessor"></span>
+00093 <span class="preprocessor">#define SDIO_STD_IFACE_UART 0x01</span>
+00094 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_STD_IFACE_BT_TYPE_A 0x02</span>
+00095 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_STD_IFACE_BT_TYPE_B 0x03</span>
+00096 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_STD_IFACE_GPS 0x04</span>
+00097 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_STD_IFACE_CAMERA 0x05</span>
+00098 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_STD_IFACE_PHS 0x06</span>
+00099 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_STD_IFACE_WLAN 0x07</span>
+00100 <span class="preprocessor"></span>
+00101 <span class="comment">/*</span>
+00102 <span class="comment"> * Manufacturer and card IDs.</span>
+00103 <span class="comment"> */</span>
+00104 <span class="preprocessor">#define SDIO_MANF_ID_CSR 0x032a</span>
+00105 <span class="preprocessor"></span>
+00106 <span class="preprocessor">#define SDIO_CARD_ID_CSR_UNIFI_1 0x0001</span>
+00107 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CARD_ID_CSR_UNIFI_2 0x0002</span>
+00108 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CARD_ID_CSR_BC6 0x0004</span>
+00109 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CARD_ID_CSR_DASH_D00 0x0005</span>
+00110 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CARD_ID_CSR_BC7 0x0006</span>
+00111 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CARD_ID_CSR_CINDERELLA 0x0007</span>
+00112 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_CARD_ID_CSR_DASH 0x0010</span>
+00113 <span class="preprocessor"></span>
+00114 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef SDIOEMB_SDIO_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio__api_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio__api_8h-source.html
new file mode 100644
index 0000000..066bc90
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio__api_8h-source.html
@@ -0,0 +1,201 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_api.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_api.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * SDIO device driver API.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SDIO_API_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SDIO_API_H</span>
+00011 <span class="preprocessor"></span>
+00033 <span class="keyword">struct </span><a class="code" href="structsdio__func__driver.html">sdio_func_driver</a>;
+00034 <span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a>;
+00035 <span class="keyword">struct </span>sdio_dev_priv;
+00036
+<a name="l00051"></a><a class="code" href="group__fdriver.html#ga0">00051</a> <span class="keyword">typedef</span> int (*<a class="code" href="group__fdriver.html#ga0">sdio_card_io_read8_t</a>)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> function,
+00052 uint32_t addr, uint8_t *data);
+00053
+<a name="l00068"></a><a class="code" href="group__fdriver.html#ga1">00068</a> <span class="keyword">typedef</span> int (*<a class="code" href="group__fdriver.html#ga1">sdio_card_io_write8_t</a>)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> function,
+00069 uint32_t addr, uint8_t data);
+00070
+<a name="l00086"></a><a class="code" href="group__fdriver.html#ga2">00086</a> <span class="keyword">typedef</span> int (*<a class="code" href="group__fdriver.html#ga2">sdio_card_io_read_t</a>)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> function,
+00087 uint32_t addr, uint8_t *data, size_t len);
+00088
+<a name="l00104"></a><a class="code" href="group__fdriver.html#ga3">00104</a> <span class="keyword">typedef</span> int (*<a class="code" href="group__fdriver.html#ga3">sdio_card_io_write_t</a>)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> function,
+00105 uint32_t addr, <span class="keyword">const</span> uint8_t *data, size_t len);
+00106
+<a name="l00112"></a><a class="code" href="structsdio__card__io__ops.html">00112</a> <span class="keyword">struct </span><a class="code" href="structsdio__card__io__ops.html">sdio_card_io_ops</a> {
+00113 <a class="code" href="group__fdriver.html#ga0">sdio_card_io_read8_t</a> read8;
+00114 <a class="code" href="group__fdriver.html#ga1">sdio_card_io_write8_t</a> write8;
+00115 <a class="code" href="group__fdriver.html#ga2">sdio_card_io_read_t</a> read;
+00116 <a class="code" href="group__fdriver.html#ga3">sdio_card_io_write_t</a> write;
+00117 };
+00118
+<a name="l00128"></a><a class="code" href="structsdio__dev.html">00128</a> <span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> {
+<a name="l00129"></a><a class="code" href="structsdio__dev.html#o0">00129</a> <span class="keyword">struct </span><a class="code" href="structsdio__func__driver.html">sdio_func_driver</a> *<a class="code" href="structsdio__dev.html#o0">driver</a>;
+<a name="l00130"></a><a class="code" href="structsdio__dev.html#o1">00130</a> uint16_t <a class="code" href="structsdio__dev.html#o1">vendor_id</a>;
+<a name="l00131"></a><a class="code" href="structsdio__dev.html#o2">00131</a> uint16_t <a class="code" href="structsdio__dev.html#o2">device_id</a>;
+<a name="l00132"></a><a class="code" href="structsdio__dev.html#o3">00132</a> <span class="keywordtype">int</span> function;
+<a name="l00133"></a><a class="code" href="structsdio__dev.html#o4">00133</a> uint8_t <a class="code" href="structsdio__dev.html#o4">interface</a>;
+<a name="l00134"></a><a class="code" href="structsdio__dev.html#o5">00134</a> <span class="keywordtype">int</span> <a class="code" href="structsdio__dev.html#o5">max_blocksize</a>;
+<a name="l00135"></a><a class="code" href="structsdio__dev.html#o6">00135</a> <span class="keywordtype">int</span> <a class="code" href="structsdio__dev.html#o6">blocksize</a>;
+<a name="l00141"></a><a class="code" href="structsdio__dev.html#o7">00141</a> <span class="keyword">struct </span><a class="code" href="structsdio__card__io__ops.html">sdio_card_io_ops</a> *<a class="code" href="structsdio__dev.html#o7">io</a>;
+<a name="l00142"></a><a class="code" href="structsdio__dev.html#o8">00142</a> <span class="keywordtype">int</span> <a class="code" href="structsdio__dev.html#o8">slot_id</a>;
+<a name="l00143"></a><a class="code" href="structsdio__dev.html#o9">00143</a> <span class="keywordtype">void</span> * <a class="code" href="structsdio__dev.html#o9">os_device</a>;
+<a name="l00144"></a><a class="code" href="structsdio__dev.html#o10">00144</a> <span class="keyword">struct </span>sdio_dev_priv * <a class="code" href="structsdio__dev.html#o10">priv</a>;
+<a name="l00145"></a><a class="code" href="structsdio__dev.html#o11">00145</a> <span class="keywordtype">void</span> * <a class="code" href="structsdio__dev.html#o11">drv_data</a>;
+00146 };
+00147
+00148 <span class="preprocessor">#define SDD_ANY_ID 0xffff</span>
+00149 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_FUNC 8</span>
+00150 <span class="preprocessor"></span><span class="preprocessor">#define SDD_ANY_FUNC 0xff</span>
+00151 <span class="preprocessor"></span><span class="preprocessor">#define SDD_ANY_IFACE 0xff</span>
+00152 <span class="preprocessor"></span>
+<a name="l00165"></a><a class="code" href="structsdio__id__table.html">00165</a> <span class="keyword">struct </span><a class="code" href="structsdio__id__table.html">sdio_id_table</a> {
+<a name="l00166"></a><a class="code" href="structsdio__id__table.html#o0">00166</a> uint16_t <a class="code" href="structsdio__id__table.html#o0">vendor_id</a>;
+<a name="l00167"></a><a class="code" href="structsdio__id__table.html#o1">00167</a> uint16_t <a class="code" href="structsdio__id__table.html#o1">device_id</a>;
+<a name="l00168"></a><a class="code" href="structsdio__id__table.html#o2">00168</a> <span class="keywordtype">int</span> function;
+<a name="l00169"></a><a class="code" href="structsdio__id__table.html#o3">00169</a> uint8_t <a class="code" href="structsdio__id__table.html#o3">interface</a>;
+00170 };
+00171
+<a name="l00177"></a><a class="code" href="structsdio__func__driver.html">00177</a> <span class="keyword">struct </span><a class="code" href="structsdio__func__driver.html">sdio_func_driver</a> {
+<a name="l00181"></a><a class="code" href="structsdio__func__driver.html#o0">00181</a> <span class="keyword">const</span> <span class="keywordtype">char</span> *<a class="code" href="structsdio__func__driver.html#o0">name</a>;
+00182
+<a name="l00190"></a><a class="code" href="structsdio__func__driver.html#o1">00190</a> <span class="keyword">struct </span><a class="code" href="structsdio__id__table.html">sdio_id_table</a> *<a class="code" href="structsdio__func__driver.html#o1">id_table</a>;
+00191
+00208 int (*probe)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00209
+00223 void (*remove)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00224
+00244 void (*card_int_handler)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00245
+00259 void (*suspend)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00260
+00275 void (*resume)(<span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00276 };
+00277
+00278 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga7">sdio_driver_register</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__func__driver.html">sdio_func_driver</a> *fdriver);
+00279 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga8">sdio_driver_unregister</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__func__driver.html">sdio_func_driver</a> *fdriver);
+00280
+00281 <span class="comment">/* For backward compatibility. */</span>
+00282 <span class="preprocessor">#define sdio_register_driver sdio_driver_register</span>
+00283 <span class="preprocessor"></span><span class="preprocessor">#define sdio_unregister_driver sdio_driver_unregister</span>
+00284 <span class="preprocessor"></span>
+00285 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga11">sdio_set_block_size</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> blksz);
+00286 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga13">sdio_set_max_bus_freq</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> max_freq);
+00287 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga14">sdio_set_bus_width</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> bus_width);
+00288
+00289 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga9">sdio_enable_function</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00290 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga10">sdio_disable_function</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00291 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga12">sdio_idle_function</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00292
+00293 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga17">sdio_read8</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t *val);
+00294 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga18">sdio_write8</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t val);
+00295 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga19">sdio_f0_read8</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t *val);
+00296 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga20">sdio_f0_write8</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint8_t val);
+00297 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga21">sdio_read</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, <span class="keywordtype">void</span> *data, size_t len);
+00298 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga22">sdio_write</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, <span class="keyword">const</span> <span class="keywordtype">void</span> *data, size_t len);
+00299
+00300 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga4">sdio_hard_reset</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00301
+00302 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga23">sdio_power_on</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00303 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga24">sdio_power_off</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00304
+00305 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga15">sdio_enable_interrupt</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *);
+00306 <span class="keywordtype">void</span> <a class="code" href="group__fdriver.html#ga16">sdio_disable_interrupt</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *);
+00307
+00308 <span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga5">sdio_cis_get_tuple</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint8_t tuple,
+00309 <span class="keywordtype">void</span> *buf, size_t len);
+00310
+<a name="l00316"></a><a class="code" href="group__fdriver.html#ga39">00316</a> <span class="keyword">enum</span> <a class="code" href="group__fdriver.html#ga39">sdio_cmd_status</a> {
+00317 <a class="code" href="group__fdriver.html#gga39a24">SDD_CMD_OK</a> = 0x00,
+00319 SDD_CMD_ERR_CMD = 0x01,
+00320 SDD_CMD_ERR_DAT = 0x02,
+00321
+00322 SDD_CMD_ERR_CRC = 0x10,
+00323 SDD_CMD_ERR_TIMEOUT = 0x20,
+00324 SDD_CMD_ERR_OTHER = 0x40,
+00325
+00326 <a class="code" href="group__fdriver.html#gga39a30">SDD_CMD_ERR_CMD_CRC</a> = SDD_CMD_ERR_CMD | SDD_CMD_ERR_CRC,
+00327 <a class="code" href="group__fdriver.html#gga39a31">SDD_CMD_ERR_CMD_TIMEOUT</a> = SDD_CMD_ERR_CMD | SDD_CMD_ERR_TIMEOUT,
+00328 <a class="code" href="group__fdriver.html#gga39a32">SDD_CMD_ERR_CMD_OTHER</a> = SDD_CMD_ERR_CMD | SDD_CMD_ERR_OTHER,
+00329 <a class="code" href="group__fdriver.html#gga39a33">SDD_CMD_ERR_DAT_CRC</a> = SDD_CMD_ERR_DAT | SDD_CMD_ERR_CRC,
+00330 <a class="code" href="group__fdriver.html#gga39a34">SDD_CMD_ERR_DAT_TIMEOUT</a> = SDD_CMD_ERR_DAT | SDD_CMD_ERR_TIMEOUT,
+00331 <a class="code" href="group__fdriver.html#gga39a35">SDD_CMD_ERR_DAT_OTHER</a> = SDD_CMD_ERR_DAT | SDD_CMD_ERR_OTHER,
+00333 <a class="code" href="group__fdriver.html#gga39a36">SDD_CMD_ERR_NO_CARD</a> = 0x04,
+00335 <a class="code" href="group__fdriver.html#gga39a37">SDD_CMD_IN_PROGRESS</a> = 0xff,
+00336 };
+00337
+<a name="l00351"></a><a class="code" href="unionsdio__response.html">00351</a> <span class="keyword">union </span><a class="code" href="unionsdio__response.html">sdio_response</a> {
+00352 uint32_t r1;
+00353 uint32_t r4;
+00354 uint32_t r5;
+00355 uint32_t r6;
+00356 };
+00357
+<a name="l00361"></a><a class="code" href="structsdio__cmd__resp.html">00361</a> <span class="keyword">struct </span><a class="code" href="structsdio__cmd__resp.html">sdio_cmd_resp</a> {
+<a name="l00362"></a><a class="code" href="structsdio__cmd__resp.html#o0">00362</a> uint8_t <a class="code" href="structsdio__cmd__resp.html#o0">cmd</a>;
+<a name="l00363"></a><a class="code" href="structsdio__cmd__resp.html#o1">00363</a> uint32_t <a class="code" href="structsdio__cmd__resp.html#o1">arg</a>;
+<a name="l00364"></a><a class="code" href="structsdio__cmd__resp.html#o2">00364</a> <span class="keyword">union </span><a class="code" href="unionsdio__response.html">sdio_response</a> response;
+00367 };
+00368
+<a name="l00372"></a><a class="code" href="structcspi__cmd__resp.html">00372</a> <span class="keyword">struct </span><a class="code" href="structcspi__cmd__resp.html">cspi_cmd_resp</a> {
+<a name="l00373"></a><a class="code" href="structcspi__cmd__resp.html#o0">00373</a> <span class="keywordtype">unsigned</span> <a class="code" href="structcspi__cmd__resp.html#o0">cmd</a> : 8;
+<a name="l00374"></a><a class="code" href="structcspi__cmd__resp.html#o1">00374</a> <span class="keywordtype">unsigned</span> addr: 24;
+<a name="l00375"></a><a class="code" href="structcspi__cmd__resp.html#o2">00375</a> uint16_t <a class="code" href="structcspi__cmd__resp.html#o2">val</a>;
+<a name="l00376"></a><a class="code" href="structcspi__cmd__resp.html#o3">00376</a> uint8_t response;
+00378 };
+00379
+00380
+<a name="l00389"></a><a class="code" href="structsdio__cmd.html">00389</a> <span class="keyword">struct </span><a class="code" href="structsdio__cmd.html">sdio_cmd</a> {
+<a name="l00394"></a><a class="code" href="structsdio__cmd.html#o0">00394</a> <span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *<a class="code" href="structsdio__cmd.html#o0">owner</a>;
+00395
+00403 void (*callback)(<span class="keyword">struct </span><a class="code" href="structsdio__cmd.html">sdio_cmd</a> *cmd);
+00404
+<a name="l00426"></a><a class="code" href="structsdio__cmd.html#o2">00426</a> <span class="keywordtype">unsigned</span> <a class="code" href="structsdio__cmd.html#o2">flags</a>;
+00427
+<a name="l00433"></a><a class="code" href="structsdio__cmd.html#o3">00433</a> <span class="keyword">struct </span><a class="code" href="structsdio__cmd__resp.html">sdio_cmd_resp</a> sdio;
+00434
+<a name="l00440"></a><a class="code" href="structsdio__cmd.html#o4">00440</a> <span class="keyword">struct </span><a class="code" href="structcspi__cmd__resp.html">cspi_cmd_resp</a> cspi;
+00441
+<a name="l00447"></a><a class="code" href="structsdio__cmd.html#o5">00447</a> uint8_t *data;
+00448
+<a name="l00455"></a><a class="code" href="structsdio__cmd.html#o6">00455</a> size_t <a class="code" href="structsdio__cmd.html#o6">len</a>;
+00456
+<a name="l00460"></a><a class="code" href="structsdio__cmd.html#o7">00460</a> <span class="keyword">enum</span> <a class="code" href="group__fdriver.html#ga39">sdio_cmd_status</a> <a class="code" href="structsdio__cmd.html#o7">status</a>;
+00461
+<a name="l00465"></a><a class="code" href="structsdio__cmd.html#o8">00465</a> <span class="keywordtype">void</span> *<a class="code" href="structsdio__cmd.html#o8">priv</a>;
+00466 };
+00467
+<a name="l00470"></a><a class="code" href="group__fdriver.html#ga25">00470</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_NONE 0x00 </span>
+<a name="l00471"></a><a class="code" href="group__fdriver.html#ga26">00471</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R1 0x01 </span>
+<a name="l00472"></a><a class="code" href="group__fdriver.html#ga27">00472</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R1B 0x02 </span>
+<a name="l00473"></a><a class="code" href="group__fdriver.html#ga28">00473</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R2 0x03 </span>
+<a name="l00474"></a><a class="code" href="group__fdriver.html#ga29">00474</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R3 0x04 </span>
+<a name="l00475"></a><a class="code" href="group__fdriver.html#ga30">00475</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R4 0x05 </span>
+<a name="l00476"></a><a class="code" href="group__fdriver.html#ga31">00476</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R5 0x06 </span>
+<a name="l00477"></a><a class="code" href="group__fdriver.html#ga32">00477</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R5B 0x07 </span>
+<a name="l00478"></a><a class="code" href="group__fdriver.html#ga33">00478</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_R6 0x08 </span>
+<a name="l00479"></a><a class="code" href="group__fdriver.html#ga34">00479</a> <span class="preprocessor">#define SDD_CMD_FLAG_RESP_MASK 0xff </span>
+00480 <span class="preprocessor">#define SDD_CMD_FLAG_RAW 0x0100 </span>
+<a name="l00481"></a><a class="code" href="group__fdriver.html#ga36">00481</a> <span class="preprocessor">#define SDD_CMD_FLAG_READ 0x0200 </span>
+<a name="l00482"></a><a class="code" href="group__fdriver.html#ga37">00482</a> <span class="preprocessor">#define SDD_CMD_FLAG_CSPI 0x0400 </span>
+<a name="l00483"></a><a class="code" href="group__fdriver.html#ga38">00483</a> <span class="preprocessor">#define SDD_CMD_FLAG_ABORT 0x0800 </span>
+00485 <span class="preprocessor"></span>
+00486 <span class="preprocessor"></span><span class="keywordtype">int</span> <a class="code" href="group__fdriver.html#ga6">sdio_start_cmd</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keyword">struct</span> <a class="code" href="structsdio__cmd.html">sdio_cmd</a> *cmd);
+00487
+00488 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SDIO_API_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio__bt__a_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio__bt__a_8h-source.html
new file mode 100644
index 0000000..294703b
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio__bt__a_8h-source.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_bt_a.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_bt_a.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * SDIO Bluetooth Type-A interface definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef SDIOEMB_SDIO_BT_A_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define SDIOEMB_SDIO_BT_A_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include &lt;sdioemb/sdio_csr.h&gt;</span>
+00013
+00014 <span class="comment">/*</span>
+00015 <span class="comment"> * Standard SDIO function registers for a Bluetooth Type-A interface.</span>
+00016 <span class="comment"> */</span>
+00017 <span class="preprocessor">#define SDIO_BT_A_RD 0x00</span>
+00018 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_BT_A_TD 0x00</span>
+00019 <span class="preprocessor"></span>
+00020 <span class="preprocessor">#define SDIO_BT_A_RX_PKT_CTRL 0x10</span>
+00021 <span class="preprocessor"></span><span class="preprocessor"># define PC_RRT 0x01</span>
+00022 <span class="preprocessor"></span>
+00023 <span class="preprocessor">#define SDIO_BT_A_TX_PKT_CTRL 0x11</span>
+00024 <span class="preprocessor"></span><span class="preprocessor"># define PC_WRT 0x01</span>
+00025 <span class="preprocessor"></span>
+00026 <span class="preprocessor">#define SDIO_BT_A_RETRY_CTRL 0x12</span>
+00027 <span class="preprocessor"></span><span class="preprocessor"># define RTC_STAT 0x01</span>
+00028 <span class="preprocessor"></span><span class="preprocessor"># define RTC_SET 0x01</span>
+00029 <span class="preprocessor"></span>
+00030 <span class="preprocessor">#define SDIO_BT_A_INTRD 0x13</span>
+00031 <span class="preprocessor"></span><span class="preprocessor"># define INTRD 0x01</span>
+00032 <span class="preprocessor"></span><span class="preprocessor"># define CL_INTRD 0x01</span>
+00033 <span class="preprocessor"></span>
+00034 <span class="preprocessor">#define SDIO_BT_A_INT_EN 0x14</span>
+00035 <span class="preprocessor"></span><span class="preprocessor"># define EN_INTRD 0x01</span>
+00036 <span class="preprocessor"></span>
+00037 <span class="preprocessor">#define SDIO_BT_A_BT_MODE 0x20</span>
+00038 <span class="preprocessor"></span><span class="preprocessor"># define MD_STAT 0x01</span>
+00039 <span class="preprocessor"></span>
+00040 <span class="comment">/*</span>
+00041 <span class="comment"> * Length of the Type-A header.</span>
+00042 <span class="comment"> *</span>
+00043 <span class="comment"> * Packet length (3 octets) plus Service ID (1 octet).</span>
+00044 <span class="comment"> */</span>
+00045 <span class="preprocessor">#define SDIO_BT_A_HEADER_LEN 4</span>
+00046 <span class="preprocessor"></span>
+00047 <span class="comment">/*</span>
+00048 <span class="comment"> * Maximum length of a Type-A transport packet.</span>
+00049 <span class="comment"> *</span>
+00050 <span class="comment"> * Type-A header length and maximum length of a HCI packet (65535</span>
+00051 <span class="comment"> * octets).</span>
+00052 <span class="comment"> */</span>
+00053 <span class="preprocessor">#define SDIO_BT_A_PACKET_LEN_MAX 65543</span>
+00054 <span class="preprocessor"></span>
+00055 <span class="keyword">enum</span> sdio_bt_a_service_id {
+00056 SDIO_BT_A_SID_CMD = 0x01,
+00057 SDIO_BT_A_SID_ACL = 0x02,
+00058 SDIO_BT_A_SID_SCO = 0x03,
+00059 SDIO_BT_A_SID_EVT = 0x04,
+00060 SDIO_BT_A_SID_VENDOR = 0xfe,
+00061 };
+00062
+00063 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> sdio_bt_a_packet_len(<span class="keyword">const</span> <span class="keywordtype">char</span> *p)
+00064 {
+00065 <span class="keywordflow">return</span> (p[0] &amp; 0xff) | ((p[1] &amp; 0xff) &lt;&lt; 8) | ((p[2] &amp; 0xff) &lt;&lt; 16);
+00066 }
+00067
+00068 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> sdio_bt_a_service_id(<span class="keyword">const</span> <span class="keywordtype">char</span> *p)
+00069 {
+00070 <span class="keywordflow">return</span> p[3];
+00071 }
+00072
+00073 <span class="keyword">struct </span>sdio_bt_a_pkt_info {
+00074 <span class="keywordtype">void</span> * data;
+00075 <span class="keywordtype">int</span> data_len; <span class="comment">/* excluding Type-A header */</span>
+00076 uint8_t hdr[SDIO_BT_A_HEADER_LEN];
+00077 uint8_t tx_data[0];
+00078 };
+00079
+00080 <span class="comment">/*</span>
+00081 <span class="comment"> * Minimum amount to read (excluding the Type-A header). This allows</span>
+00082 <span class="comment"> * short packets (e.g., flow control packets) to be read with a single</span>
+00083 <span class="comment"> * command.</span>
+00084 <span class="comment"> */</span>
+00085 <span class="preprocessor">#define SDIO_BT_A_MIN_READ (32 - SDIO_BT_A_HEADER_LEN)</span>
+00086 <span class="preprocessor"></span>
+00087 <span class="preprocessor">#define SDIO_BT_A_NAME_LEN 16</span>
+00088 <span class="preprocessor"></span>
+00089 <span class="keyword">struct </span>sdio_bt_a_dev {
+00090 <span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev;
+00091 <span class="keywordtype">char</span> name[SDIO_BT_A_NAME_LEN];
+00092 <span class="keywordtype">void</span> *drv_data;
+00093
+00094 void (*receive)(<span class="keyword">struct </span>sdio_bt_a_dev *bt, <span class="keyword">struct </span>sdio_bt_a_pkt_info *pkt);
+00095 void (*sleep_state_changed)(<span class="keyword">struct </span>sdio_bt_a_dev *bt);
+00096
+00097 <span class="keyword">enum</span> <a class="code" href="group__registers.html#ga11">sdio_sleep_state</a> sleep_state;
+00098
+00099 uint8_t max_tx_retries;
+00100 uint8_t max_rx_retries;
+00101 <span class="keywordtype">unsigned</span> needs_read_ack:1;
+00102 <span class="keywordtype">unsigned</span> wait_for_firmware:1;
+00103 };
+00104
+00105 <span class="keywordtype">void</span> sdio_bt_a_init(<span class="keyword">struct</span> sdio_bt_a_dev *bt, <span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00106 <span class="keywordtype">int</span> sdio_bt_a_send(<span class="keyword">struct</span> sdio_bt_a_dev *bt, <span class="keyword">const</span> <span class="keyword">struct</span> sdio_bt_a_pkt_info *pkt);
+00107 <span class="keywordtype">void</span> sdio_bt_a_handle_interrupt(<span class="keyword">struct</span> sdio_bt_a_dev *bt);
+00108 <span class="keywordtype">void</span> sdio_bt_a_set_sleep_state(<span class="keyword">struct</span> sdio_bt_a_dev *bt, <span class="keyword">enum</span> sdio_sleep_state state);
+00109 <span class="keywordtype">int</span> sdio_bt_a_check_for_reset(<span class="keyword">struct</span> sdio_bt_a_dev *bt);
+00110 <span class="keywordtype">void</span> sdio_bt_a_start(<span class="keyword">struct</span> sdio_bt_a_dev *bt);
+00111 <span class="keywordtype">void</span> sdio_bt_a_stop(<span class="keyword">struct</span> sdio_bt_a_dev *bt);
+00112
+00113 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef SDIOEMB_SDIO_BT_A_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio__cis_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio__cis_8h-source.html
new file mode 100644
index 0000000..7335cbb
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio__cis_8h-source.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_cis.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_cis.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * SDIO CIS definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SDIO_CIS_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SDIO_CIS_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#define CISTPL_NULL 0x00</span>
+00013 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_CHECKSUM 0x10</span>
+00014 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_VERS_1 0x15</span>
+00015 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_ALTSTR 0x16</span>
+00016 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_MANFID 0x20</span>
+00017 <span class="preprocessor"></span><span class="preprocessor"># define CISTPL_MANFID_SIZE 0x04</span>
+00018 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_FUNCID 0x21</span>
+00019 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_FUNCE 0x22</span>
+00020 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_SDIO_STD 0x91</span>
+00021 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_SDIO_EXT 0x92</span>
+00022 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_END 0xff</span>
+00023 <span class="preprocessor"></span><span class="preprocessor">#define CISTPL_FUNCE 0x22</span>
+00024 <span class="preprocessor"></span><span class="preprocessor"># define CISTPL_FUNCE_00_SIZE 0x04</span>
+00025 <span class="preprocessor"></span><span class="preprocessor"># define CISTPL_FUNCE_01_SIZE 0x2a</span>
+00026 <span class="preprocessor"></span>
+00027 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SDIO_CIS_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio__config_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio__config_8h-source.html
new file mode 100644
index 0000000..41fffad
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio__config_8h-source.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/sdio_config.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/sdio_config.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Compile time configuration defaults.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SDD_CONFIG_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SDD_CONFIG_H</span>
+00011 <span class="preprocessor"></span>
+00029 <span class="preprocessor">#ifndef SDD_SLOTS_MAX</span>
+<a name="l00030"></a><a class="code" href="group__config.html#ga0">00030</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_SLOTS_MAX 4</span>
+00031 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00032 <span class="preprocessor"></span>
+00039 <span class="preprocessor">#ifndef SDD_FDRIVERS_MAX</span>
+<a name="l00040"></a><a class="code" href="group__config.html#ga1">00040</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_FDRIVERS_MAX 4</span>
+00041 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00042 <span class="preprocessor"></span>
+00048 <span class="preprocessor">#ifndef SDD_FDEVS_MAX</span>
+<a name="l00049"></a><a class="code" href="group__config.html#ga2">00049</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_FDEVS_MAX 8</span>
+00050 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00051 <span class="preprocessor"></span>
+00057 <span class="preprocessor">#ifndef SDD_CARD_INIT_RETRY_MAX</span>
+<a name="l00058"></a><a class="code" href="group__config.html#ga3">00058</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_CARD_INIT_RETRY_MAX 3</span>
+00059 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00060 <span class="preprocessor"></span>
+00067 <span class="preprocessor">#ifndef SDD_CARD_READY_TIMEOUT_MS</span>
+<a name="l00068"></a><a class="code" href="group__config.html#ga4">00068</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_CARD_READY_TIMEOUT_MS 100</span>
+00069 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00070 <span class="preprocessor"></span>
+00079 <span class="preprocessor">#ifndef SDD_CARD_IS_REMOVABLE</span>
+<a name="l00080"></a><a class="code" href="group__config.html#ga5">00080</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_CARD_IS_REMOVABLE 1</span>
+00081 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00082 <span class="preprocessor"></span>
+00089 <span class="preprocessor">#ifndef SDD_CSPI_REG_PADDING</span>
+<a name="l00090"></a><a class="code" href="group__config.html#ga6">00090</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_CSPI_REG_PADDING 0</span>
+00091 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00092 <span class="preprocessor"></span>
+00099 <span class="preprocessor">#ifndef SDD_CSPI_BURST_PADDING</span>
+<a name="l00100"></a><a class="code" href="group__config.html#ga7">00100</a> <span class="preprocessor"></span><span class="preprocessor"># define SDD_CSPI_BURST_PADDING 2</span>
+00101 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00102 <span class="preprocessor"></span>
+00105 <span class="preprocessor">#endif </span><span class="comment">/* _SDD_CONFIG_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio__csr_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio__csr_8h-source.html
new file mode 100644
index 0000000..9f2fc4f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio__csr_8h-source.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_csr.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/sdio_csr.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * CSR specific SDIO registers.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef SDIOEMB_SDIO_CSR_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define SDIOEMB_SDIO_CSR_H</span>
+00011 <span class="preprocessor"></span>
+<a name="l00031"></a><a class="code" href="group__registers.html#ga0">00031</a> <span class="preprocessor">#define SDIO_CSR_SLEEP_STATE 0xf0</span>
+00032 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CSR_SLEEP_STATE_FUNC(f) ((f) &lt;&lt; 4)</span>
+00033 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CSR_SLEEP_STATE_RDY_INT_EN 0x02</span>
+00034 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CSR_SLEEP_STATE_WAKE_REQ 0x01</span>
+00035 <span class="preprocessor"></span>
+<a name="l00042"></a><a class="code" href="group__registers.html#ga4">00042</a> <span class="preprocessor">#define SDIO_CSR_HOST_INT 0xf1</span>
+00043 <span class="preprocessor"></span><span class="preprocessor"># define SDIO_CSR_HOST_INT_CL 0x01</span>
+00044 <span class="preprocessor"></span>
+<a name="l00054"></a><a class="code" href="group__registers.html#ga6">00054</a> <span class="preprocessor">#define SDIO_CSR_FROM_HOST_SCRATCH0 0xf2</span>
+00055 <span class="preprocessor"></span>
+<a name="l00061"></a><a class="code" href="group__registers.html#ga7">00061</a> <span class="preprocessor">#define SDIO_CSR_FROM_HOST_SCRATCH1 0xf3</span>
+00062 <span class="preprocessor"></span>
+<a name="l00072"></a><a class="code" href="group__registers.html#ga8">00072</a> <span class="preprocessor">#define SDIO_CSR_TO_HOST_SCRATCH0 0xf4</span>
+00073 <span class="preprocessor"></span>
+<a name="l00079"></a><a class="code" href="group__registers.html#ga9">00079</a> <span class="preprocessor">#define SDIO_CSR_TO_HOST_SCRATCH1 0xf5</span>
+00080 <span class="preprocessor"></span>
+<a name="l00091"></a><a class="code" href="group__registers.html#ga10">00091</a> <span class="preprocessor">#define SDIO_CSR_EXT_IO_EN 0xf6</span>
+00092 <span class="preprocessor"></span>
+<a name="l00115"></a><a class="code" href="group__registers.html#ga11">00115</a> <span class="keyword">enum</span> <a class="code" href="group__registers.html#ga11">sdio_sleep_state</a> {
+00116 SLEEP_STATE_AWAKE = SDIO_CSR_SLEEP_STATE_WAKE_REQ,
+00117 SLEEP_STATE_DROWSY = SDIO_CSR_SLEEP_STATE_WAKE_REQ | SDIO_CSR_SLEEP_STATE_RDY_INT_EN,
+00118 SLEEP_STATE_TORPID = 0x00,
+00119 };
+00120
+00123 <span class="comment">/*</span>
+00124 <span class="comment"> * Generic function registers (with byte addresses).</span>
+00125 <span class="comment"> */</span>
+00126
+00127 <span class="comment">/*</span>
+00128 <span class="comment"> * SDIO_MODE is chip dependant, see the sdio_mode table in sdio_cspi.c</span>
+00129 <span class="comment"> * to add support for new chips.</span>
+00130 <span class="comment"> */</span>
+00131 <span class="preprocessor">#define SDIO_MODE </span><span class="comment">/* chip dependant */</span>
+00132 <span class="preprocessor"># define SDIO_MODE_CSPI_EN 0x40</span>
+00133 <span class="preprocessor"></span>
+00134 <span class="preprocessor">#endif </span><span class="comment">/* SDIOEMB_SDIO_CSR_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio__event__log_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio__event__log_8h-source.html
new file mode 100644
index 0000000..8070a0f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio__event__log_8h-source.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/sdio_event_log.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/sdio_event_log.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Manage a log of the most recent SDIO events (commands and</span>
+00003 <span class="comment"> * interrupts etc.).</span>
+00004 <span class="comment"> *</span>
+00005 <span class="comment"> * Enable the log by #define'ing SDD_DEBUG_EVENT_LOG_LEN to the</span>
+00006 <span class="comment"> * maximum number of events to keep in the log.</span>
+00007 <span class="comment"> *</span>
+00008 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00009 <span class="comment"> *</span>
+00010 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00011 <span class="comment"> * the license terms.</span>
+00012 <span class="comment"> */</span>
+00013
+00014 <span class="preprocessor">#ifndef _SDIO_EVENT_LOG_H</span>
+00015 <span class="preprocessor"></span><span class="preprocessor">#define _SDIO_EVENT_LOG_H</span>
+00016 <span class="preprocessor"></span>
+00017 <span class="preprocessor">#ifdef __linux</span>
+00018 <span class="preprocessor"></span><span class="preprocessor"># define SDD_DEBUG_HAVE_EVENT_LOG</span>
+00019 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00020 <span class="preprocessor"></span>
+00021 <span class="preprocessor">#ifndef SDD_DEBUG_EVENT_LOG_LEN</span>
+00022 <span class="preprocessor"></span><span class="preprocessor"># define SDD_DEBUG_EVENT_LOG_LEN 0</span>
+00023 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00024 <span class="preprocessor"></span>
+00025 <span class="preprocessor">#ifndef SDD_DEBUG_DATA_BUFFER_LEN</span>
+00026 <span class="preprocessor"></span><span class="preprocessor"># define SDD_DEBUG_DATA_BUFFER_LEN 0</span>
+00027 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+00028 <span class="preprocessor"></span>
+00029 <span class="preprocessor">#if SDD_DEBUG_EVENT_LOG_LEN &gt; 0 &amp;&amp; defined(SDD_DEBUG_HAVE_EVENT_LOG)</span>
+00030 <span class="preprocessor"></span>
+00031 <span class="preprocessor">#define SDD_DEBUG_EVENT_LOG</span>
+00032 <span class="preprocessor"></span>
+00033 <span class="keyword">enum</span> sdio_event_type {
+00034 SDD_EVENT_CMD, SDD_EVENT_CARD_INT,
+00035 SDD_EVENT_INT_UNMASKED, SDD_EVENT_INT_MASKED,
+00036 SDD_EVENT_POWER_ON, SDD_EVENT_POWER_OFF, SDD_EVENT_RESET,
+00037 SDD_EVENT_CLOCK_FREQ,
+00038 };
+00039
+00040 <span class="keyword">struct </span>sdio_event_entry {
+00041 <span class="keywordtype">unsigned</span> seq_num;
+00042 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> time_ms;
+00043 <span class="keyword">enum</span> sdio_event_type type;
+00044 <span class="keyword">union </span>{
+00045 <span class="keyword">struct </span>{
+00046 <span class="keywordtype">unsigned</span> flags;
+00047 <span class="keyword">union </span>{
+00048 <span class="keyword">struct </span><a class="code" href="structsdio__cmd__resp.html">sdio_cmd_resp</a> sdio;
+00049 <span class="keyword">struct </span><a class="code" href="structcspi__cmd__resp.html">cspi_cmd_resp</a> cspi;
+00050 };
+00051 <span class="keywordtype">int</span> status;
+00052 <span class="preprocessor">#if SDD_DEBUG_DATA_BUFFER_LEN &gt; 0</span>
+00053 <span class="preprocessor"></span> <span class="keyword">struct </span>{
+00054 <span class="keywordtype">unsigned</span> length;
+00055 <span class="keywordtype">unsigned</span> start;
+00056 uint8_t *buffer;
+00057 <span class="keyword">struct </span>sdio_event_entry *next;
+00058 } data;
+00059 <span class="preprocessor">#endif</span>
+00060 <span class="preprocessor"></span> } cmd;
+00061 <span class="keywordtype">unsigned</span> functions; <span class="comment">/*&lt; bit mask of relevant functions */</span>
+00062 <span class="keywordtype">int</span> val;
+00063 };
+00064 };
+00065
+00066 <span class="comment">/* A ring buffer of SDIO events. */</span>
+00067 <span class="keyword">struct </span>sdio_event_log {
+00068 <span class="keyword">struct </span>sdio_event_entry *entries;
+00069 <span class="keywordtype">unsigned</span> head;
+00070 <span class="keywordtype">unsigned</span> tail;
+00071 <span class="keywordtype">unsigned</span> seq_num;
+00072 os_spinlock_t lock;
+00073
+00074 <span class="preprocessor">#if SDD_DEBUG_DATA_BUFFER_LEN &gt; 0</span>
+00075 <span class="preprocessor"></span> <span class="comment">/*</span>
+00076 <span class="comment"> * So that we don't display old data but can limit ourselves to</span>
+00077 <span class="comment"> * the last n octets of interesting data I play some clever tricks</span>
+00078 <span class="comment"> * here. I store the sdio_cmd_event's that refer to data in a</span>
+00079 <span class="comment"> * linked list and also store the length of data blocks in this</span>
+00080 <span class="comment"> * list. When I add a new block to the tail of this list that</span>
+00081 <span class="comment"> * increases the data size past the size of sdio_data_buffer I</span>
+00082 <span class="comment"> * chop things off the head of the list until the size is OK</span>
+00083 <span class="comment"> * again.</span>
+00084 <span class="comment"> */</span>
+00085 uint8_t *data_buffer;
+00086 <span class="keywordtype">unsigned</span> data_start;
+00087 <span class="keywordtype">unsigned</span> data_total;
+00088 <span class="keyword">struct </span>sdio_event_entry *data_head;
+00089 <span class="keyword">struct </span>sdio_event_entry *data_tail;
+00090 <span class="preprocessor">#endif</span>
+00091 <span class="preprocessor"></span>};
+00092
+00093 <span class="keywordtype">void</span> sdio_event_log_init(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00094 <span class="keywordtype">void</span> sdio_event_log_deinit(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00095 <span class="keywordtype">void</span> sdio_event_log(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">enum</span> sdio_event_type type, ...);
+00096 <span class="keywordtype">void</span> sdio_event_log_set_response(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">const</span> <span class="keyword">struct</span> <a class="code" href="structsdio__cmd.html">sdio_cmd</a> *cmd);
+00097
+00098 <span class="keyword">struct </span>sdio_event_entry *sdio_event_log_get_entry(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keywordtype">unsigned</span> n);
+00099 uint8_t sdio_event_log_get_data(<span class="keyword">struct</span> sdio_event_entry *e, <span class="keywordtype">unsigned</span> i);
+00100
+00101 <span class="keywordtype">void</span> sdio_os_event_log_init(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00102 <span class="keywordtype">void</span> sdio_os_event_log_deinit(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00103
+00104 <span class="preprocessor">#else</span>
+00105 <span class="preprocessor"></span>
+00106 <span class="preprocessor">#undef SDD_DEBUG_EVENT_LOG</span>
+00107 <span class="preprocessor"></span>
+00108 <span class="preprocessor">#define sdio_event_log_init(s)</span>
+00109 <span class="preprocessor"></span><span class="preprocessor">#define sdio_event_log_deinit(s)</span>
+00110 <span class="preprocessor"></span><span class="preprocessor">#define sdio_event_log(s, t, ...)</span>
+00111 <span class="preprocessor"></span><span class="preprocessor">#define sdio_event_log_set_response(s, c)</span>
+00112 <span class="preprocessor"></span>
+00113 <span class="preprocessor">#endif</span>
+00114 <span class="preprocessor"></span>
+00115 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SDIO_EVENT_LOG_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/sdio__layer_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/sdio__layer_8h-source.html
new file mode 100644
index 0000000..ab2656a
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/sdio__layer_8h-source.html
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/sdio_layer.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/sdio_layer.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Internal/private definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SDIO_LAYER_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SDIO_LAYER_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include &lt;oska/all.h&gt;</span>
+00013
+00014 <span class="preprocessor">#include &lt;sdioemb/sdio.h&gt;</span>
+00015 <span class="preprocessor">#include &lt;sdioemb/sdio_api.h&gt;</span>
+00016 <span class="preprocessor">#include &lt;sdioemb/slot_api.h&gt;</span>
+00017
+00018 <span class="preprocessor">#include "sdio_event_log.h"</span>
+00019 <span class="preprocessor">#include "sdio_config.h"</span>
+00020
+00021 <span class="preprocessor">#define SDD_MAX_FUNCTIONS (SDIO_MAX_FUNCTIONS + 1) </span><span class="comment">/* extra for uif function */</span>
+00022
+00023 <span class="keyword">struct </span>sdio_slot_priv {
+00024 <span class="keywordtype">int</span> id;
+00025
+00026 <span class="keywordtype">unsigned</span> card_present:1;
+00027 <span class="keywordtype">unsigned</span> card_powered:1;
+00028
+00029 <span class="keywordtype">int</span> num_functions;
+00030 <span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *functions[SDD_MAX_FUNCTIONS];
+00031 <span class="keywordtype">int</span> max_bus_width;
+00032 <span class="keywordtype">int</span> max_card_freq;
+00033 <span class="keywordtype">int</span> current_clock_freq;
+00034 <span class="keywordtype">unsigned</span> supports_high_speed:1;
+00035
+00036 <span class="keyword">struct </span><a class="code" href="structsdio__card__io__ops.html">sdio_card_io_ops</a> io_ops;
+00037
+00038 os_spinlock_t lock;
+00039
+00040 <span class="keywordtype">unsigned</span> active;
+00041 <span class="keywordtype">unsigned</span> power;
+00042 <span class="keywordtype">unsigned</span> int_enabled;
+00043
+00044 <span class="keywordtype">int</span> busy;
+00045 <span class="keywordtype">int</span> last_function;
+00046 <span class="preprocessor">#if SDD_CARD_IS_REMOVABLE</span>
+00047 <span class="preprocessor"></span> os_thread_t card_detect_thread;
+00048 <span class="preprocessor">#endif</span>
+00049 <span class="preprocessor"></span> os_mutex_t card_mutex;
+00050
+00051 <span class="preprocessor">#ifdef SDD_DEBUG_EVENT_LOG</span>
+00052 <span class="preprocessor"></span> <span class="keyword">struct </span>sdio_event_log event_log;
+00053 <span class="preprocessor">#endif</span>
+00054 <span class="preprocessor"></span>};
+00055
+00056 <span class="keyword">struct </span>sdio_dev_priv {
+00057 <span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot;
+00058 uint32_t cis_ptr;
+00059 <span class="keywordtype">int</span> max_freq;
+00060 <span class="keyword">struct </span><a class="code" href="structsdio__cmd.html">sdio_cmd</a> *queued_cmd;
+00061 };
+00062
+00063 <span class="keywordtype">void</span> slot_error(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, ...);
+00064 <span class="keywordtype">void</span> slot_warning(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, ...);
+00065 <span class="keywordtype">void</span> slot_info(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, ...);
+00066 <span class="keywordtype">void</span> slot_debug(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">const</span> <span class="keywordtype">char</span> *fmt, ...);
+00067
+00068 <span class="keywordtype">void</span> sdio_core_init(<span class="keywordtype">void</span>);
+00069 <span class="keyword">struct </span><a class="code" href="structsdio__dev.html">sdio_dev</a> *sdio_dev_alloc(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keywordtype">int</span> func);
+00070 <span class="keywordtype">void</span> sdio_dev_free(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00071 <span class="keywordtype">int</span> sdio_dev_add(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00072 <span class="keywordtype">void</span> sdio_dev_del(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00073
+00074 <span class="keywordtype">int</span> sdio_card_detect_init(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00075 <span class="keywordtype">void</span> sdio_card_detect_exit(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00076 <span class="keywordtype">int</span> sdio_card_start(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00077 <span class="keywordtype">void</span> sdio_card_stop(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00078 <span class="keywordtype">void</span> sdio_card_configure(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00079
+00080 <span class="keywordtype">int</span> slot_start_cmd(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">struct</span> <a class="code" href="structsdio__cmd.html">sdio_cmd</a> *cmd);
+00081 <span class="keywordtype">void</span> slot_set_max_bus_freq(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keywordtype">int</span> freq);
+00082 <span class="keywordtype">void</span> slot_set_bus_freq(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keywordtype">int</span> freq);
+00083 <span class="keywordtype">int</span> slot_set_bus_width(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keywordtype">int</span> bus_width);
+00084
+00085 <span class="keywordtype">int</span> sdio_func_set_block_size(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> blksz);
+00086 <span class="keywordtype">void</span> sdio_func_set_max_bus_freq(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> max_freq);
+00087
+00088 <span class="keywordtype">int</span> sdio_cis_read_ptr_reg(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, uint32_t addr, uint32_t *ptr);
+00089
+00090 <span class="keywordtype">int</span> sdio_raw_cmd(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, uint8_t cmd_id, uint32_t arg, <span class="keywordtype">unsigned</span> flags,
+00091 <span class="keyword">union</span> <a class="code" href="unionsdio__response.html">sdio_response</a> *response);
+00092 <span class="keywordtype">int</span> cspi_raw_word_cmd(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, uint8_t cmd_id, uint32_t addr, uint16_t *word);
+00093
+00094 <span class="keywordtype">int</span> sdio_io_read8(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data);
+00095 <span class="keywordtype">int</span> sdio_io_write8(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t data);
+00096 <span class="keywordtype">int</span> sdio_io_read(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data, size_t len);
+00097 <span class="keywordtype">int</span> sdio_io_write(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, <span class="keyword">const</span> uint8_t *data, size_t len);
+00098
+00099 <span class="keywordtype">int</span> cspi_io_read8(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data);
+00100 <span class="keywordtype">int</span> cspi_io_write8(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t data);
+00101 <span class="keywordtype">int</span> cspi_io_read(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, uint8_t *data, size_t len);
+00102 <span class="keywordtype">int</span> cspi_io_write(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev, <span class="keywordtype">int</span> func, uint32_t addr, <span class="keyword">const</span> uint8_t *data, size_t len);
+00103
+00104 <span class="keywordtype">int</span> cspi_is_enabled(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00105 <span class="keywordtype">int</span> cspi_card_init(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00106 <span class="keywordtype">int</span> cspi_enable(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00107
+00108 <span class="keyword">extern</span> <span class="keywordtype">int</span> sdd_card_poll_interval_ms;
+00109 <span class="keyword">extern</span> <span class="keywordtype">int</span> sdd_max_bus_freq;
+00110 <span class="keyword">extern</span> <span class="keywordtype">int</span> sdd_max_block_size;
+00111
+00112 <span class="keyword">extern</span> os_mutex_t sdio_core_mutex;
+00113
+00114 <span class="comment">/*</span>
+00115 <span class="comment"> * Hooks for managing OS-specific device structures.</span>
+00116 <span class="comment"> */</span>
+00117 <span class="keywordtype">int</span> sdio_os_dev_add(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00118 <span class="keywordtype">void</span> sdio_os_dev_del(<span class="keyword">struct</span> <a class="code" href="structsdio__dev.html">sdio_dev</a> *fdev);
+00119
+00120 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SDIO_LAYER_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__api_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__api_8h-source.html
new file mode 100644
index 0000000..38cde04
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__api_8h-source.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/slot_api.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/slot_api.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Slot driver API.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_API_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_API_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include &lt;sdioemb/sdio_api.h&gt;</span>
+00013
+00029 <span class="preprocessor">#define SDD_BUS_FREQ_OFF 0</span>
+00030 <span class="preprocessor"></span><span class="preprocessor">#define SDD_BUS_FREQ_DEFAULT -1</span>
+00031 <span class="preprocessor"></span><span class="preprocessor">#define SDD_BUS_FREQ_IDLE -2</span>
+00032 <span class="preprocessor"></span>
+<a name="l00038"></a><a class="code" href="group__sdriver.html#ga32">00038</a> <span class="keyword">enum</span> <a class="code" href="group__sdriver.html#ga32">sdio_power</a> {
+00039 <a class="code" href="group__sdriver.html#gga32a3">SDIO_POWER_OFF</a> = 0,
+00040 <a class="code" href="group__sdriver.html#gga32a4">SDIO_POWER_3V3</a> = 33,
+00041 };
+00042
+<a name="l00048"></a><a class="code" href="structslot__caps.html">00048</a> <span class="keyword">struct </span><a class="code" href="structslot__caps.html">slot_caps</a> {
+<a name="l00049"></a><a class="code" href="structslot__caps.html#o0">00049</a> <span class="keywordtype">int</span> <a class="code" href="structslot__caps.html#o0">max_bus_freq</a>;
+<a name="l00050"></a><a class="code" href="structslot__caps.html#o1">00050</a> <span class="keywordtype">int</span> <a class="code" href="structslot__caps.html#o1">max_bus_width</a>;
+<a name="l00051"></a><a class="code" href="structslot__caps.html#o2">00051</a> uint8_t <a class="code" href="structslot__caps.html#o2">cspi_mode</a>;
+00052 };
+00053
+00057 <span class="keyword">enum</span> slot_controller_type {
+00058 SDD_SLOT_TYPE_SD = 0,
+00059 SDD_SLOT_TYPE_SPI,
+00060 SDD_SLOT_TYPE_SPI_CSPI,
+00061 };
+00062
+00063 <span class="keyword">struct </span>sdio_slot_priv;
+00064
+<a name="l00072"></a><a class="code" href="structsdio__slot.html">00072</a> <span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> {
+<a name="l00079"></a><a class="code" href="structsdio__slot.html#o0">00079</a> <span class="keywordtype">char</span> <a class="code" href="structsdio__slot.html#o0">name</a>[64];
+00080
+<a name="l00084"></a><a class="code" href="structsdio__slot.html#o1">00084</a> <span class="keyword">enum</span> slot_controller_type <a class="code" href="structsdio__slot.html#o1">type</a>;
+00085
+00114 int (*set_bus_freq)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keywordtype">int</span> clk);
+00115
+00133 int (*set_bus_width)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keywordtype">int</span> <a class="code" href="structsdio__slot.html#o12">bus_width</a>);
+00134
+00148 int (*start_cmd)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">struct </span><a class="code" href="structsdio__cmd.html">sdio_cmd</a> *cmd);
+00149
+00159 int (*card_present)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00160
+00172 int (*card_power)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">enum</span> <a class="code" href="group__sdriver.html#ga32">sdio_power</a> power);
+00173
+00181 void (*enable_card_int)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00182
+00190 void (*disable_card_int)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00191
+00208 int (*hard_reset)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00209
+<a name="l00210"></a><a class="code" href="structsdio__slot.html#o10">00210</a> <span class="keyword">struct </span><a class="code" href="structslot__caps.html">slot_caps</a> caps;
+<a name="l00211"></a><a class="code" href="structsdio__slot.html#o11">00211</a> <span class="keywordtype">int</span> <a class="code" href="structsdio__slot.html#o11">clock_freq</a>;
+<a name="l00212"></a><a class="code" href="structsdio__slot.html#o12">00212</a> <span class="keywordtype">int</span> <a class="code" href="structsdio__slot.html#o12">bus_width</a>;
+<a name="l00213"></a><a class="code" href="structsdio__slot.html#o13">00213</a> <span class="keywordtype">int</span> <a class="code" href="structsdio__slot.html#o13">cspi_reg_pad</a>;
+<a name="l00214"></a><a class="code" href="structsdio__slot.html#o14">00214</a> <span class="keywordtype">int</span> <a class="code" href="structsdio__slot.html#o14">cspi_burst_pad</a>;
+<a name="l00215"></a><a class="code" href="structsdio__slot.html#o15">00215</a> <span class="keyword">struct </span>sdio_slot_priv *<a class="code" href="structsdio__slot.html#o15">priv</a>;
+<a name="l00216"></a><a class="code" href="structsdio__slot.html#o16">00216</a> <span class="keywordtype">void</span> * <a class="code" href="structsdio__slot.html#o16">drv_data</a>;
+00217 };
+00218
+00219 <span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *<a class="code" href="group__sdriver.html#ga6">sdio_slot_alloc</a>(size_t drv_data_size);
+00220 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga7">sdio_slot_free</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00221 <span class="keywordtype">int</span> <a class="code" href="group__sdriver.html#ga8">sdio_slot_register</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00222 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga9">sdio_slot_unregister</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00223 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga0">sdio_card_inserted</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00224 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga1">sdio_card_removed</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00225 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga3">sdio_interrupt</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00226 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga2">sdio_cmd_complete</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot, <span class="keyword">struct</span> <a class="code" href="structsdio__cmd.html">sdio_cmd</a> *cmd);
+00227
+00228 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga4">sdio_suspend</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00229 <span class="keywordtype">void</span> <a class="code" href="group__sdriver.html#ga5">sdio_resume</a>(<span class="keyword">struct</span> <a class="code" href="structsdio__slot.html">sdio_slot</a> *slot);
+00230
+00231
+00232 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_API_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__imx27_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__imx27_8h-source.html
new file mode 100644
index 0000000..e0ad5f1
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__imx27_8h-source.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx27.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx27.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * i.MX27 SDHC definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_IMX27_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_IMX27_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="comment">/*</span>
+00013 <span class="comment"> * i.MX27 SDHC registers.</span>
+00014 <span class="comment"> */</span>
+00015
+00016 <span class="preprocessor">#define SDHC_STR_STP_CLK 0x00</span>
+00017 <span class="preprocessor"></span><span class="preprocessor"># define STR_STP_CLK_MMCSD_RESET 0x0008</span>
+00018 <span class="preprocessor"></span><span class="preprocessor"># define STR_STP_CLK_START_CLK 0x0002</span>
+00019 <span class="preprocessor"></span><span class="preprocessor"># define STR_STP_CLK_STOP_CLK 0x0001</span>
+00020 <span class="preprocessor"></span>
+00021 <span class="preprocessor">#define SDHC_STATUS 0x04</span>
+00022 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CARD_PRESENCE 0x8000</span>
+00023 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_SDIO_INT_ACTIVE 0x4000</span>
+00024 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_END_CMD_RESP 0x2000</span>
+00025 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_WRITE_OP_DONE 0x1000</span>
+00026 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_READ_OP_DONE 0x0800</span>
+00027 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CARD_BUS_CLK_RUN 0x0100</span>
+00028 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_APPL_BUFF_FF 0x0080</span>
+00029 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_APPL_BUFF_FE 0x0040</span>
+00030 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_RESP_CRC_ERR 0x0020</span>
+00031 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CRC_READ_ERR 0x0008</span>
+00032 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CRC_WRITE_ERR 0x0004</span>
+00033 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_TIME_OUT_RESP 0x0002</span>
+00034 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_TIME_OUT_READ 0x0001</span>
+00035 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP)</span>
+00036 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ)</span>
+00037 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK)</span>
+00038 <span class="preprocessor"></span>
+00039 <span class="preprocessor">#define SDHC_CLK_RATE 0x08</span>
+00040 <span class="preprocessor"></span>
+00041 <span class="preprocessor">#define SDHC_CMD_DAT_CTRL 0x0c </span><span class="comment">/* CMD_DAT_CONT */</span>
+00042 <span class="preprocessor"># define CMD_DAT_CTRL_CMD_RESUME 0x8000</span>
+00043 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000</span>
+00044 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800</span>
+00045 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_START_READ_WAIT 0x0400</span>
+00046 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200</span>
+00047 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_INIT 0x0080</span>
+00048 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_WRITE 0x0010</span>
+00049 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_DATA_ENABLE 0x0008</span>
+00050 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_NONE 0x0000</span>
+00051 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001</span>
+00052 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_R2 0x0002</span>
+00053 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_R3_R4 0x0003</span>
+00054 <span class="preprocessor"></span>
+00055 <span class="preprocessor">#define SDHC_RES_TO 0x10</span>
+00056 <span class="preprocessor"></span>
+00057 <span class="preprocessor">#define SDHC_READ_TO 0x14</span>
+00058 <span class="preprocessor"></span><span class="preprocessor"># define READ_TO_RECOMMENDED 0x2db4</span>
+00059 <span class="preprocessor"></span>
+00060 <span class="preprocessor">#define SDHC_BLK_LEN 0x18</span>
+00061 <span class="preprocessor"></span>
+00062 <span class="preprocessor">#define SDHC_NOB 0x1c</span>
+00063 <span class="preprocessor"></span>
+00064 <span class="preprocessor">#define SDHC_REV_NO 0x20</span>
+00065 <span class="preprocessor"></span>
+00066 <span class="preprocessor">#define SDHC_INT_CTRL 0x24 </span><span class="comment">/* INT_CNTR */</span>
+00067 <span class="preprocessor"># define INT_CTRL_CARD_INSERTION_EN 0x8000</span>
+00068 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_SDIO_REMOVAL_EN 0x4000</span>
+00069 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_SDIO_IRQ_EN 0x2000</span>
+00070 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_DAT0_EN 0x1000</span>
+00071 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_BUF_READ_EN 0x0010</span>
+00072 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_BUF_WRITE_EN 0x0008</span>
+00073 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_END_CMD_RES 0x0004</span>
+00074 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_WRITE_OP_DONE 0x0002</span>
+00075 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_READ_OP_DONE 0x0001</span>
+00076 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_INT_EN_MASK 0xe01f</span>
+00077 <span class="preprocessor"></span>
+00078 <span class="preprocessor">#define SDHC_CMD 0x28</span>
+00079 <span class="preprocessor"></span>
+00080 <span class="preprocessor">#define SDHC_ARG 0x2c</span>
+00081 <span class="preprocessor"></span>
+00082 <span class="preprocessor">#define SDHC_RES_FIFO 0x34</span>
+00083 <span class="preprocessor"></span>
+00084 <span class="preprocessor">#define SDHC_BUFFER_ACCESS 0x38</span>
+00085 <span class="preprocessor"></span>
+00086 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_IMX27_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__imx27__lx_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__imx27__lx_8h-source.html
new file mode 100644
index 0000000..c5dbf36
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__imx27__lx_8h-source.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx27_lx.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx27_lx.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Linux i.MX27 slot driver platform data definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_IMX27_LX_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_IMX27_LX_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include &lt;sdioemb/slot_api.h&gt;</span>
+00013
+00014 <span class="keyword">struct </span>imx_sdio_plat_data {
+00015 <span class="keywordtype">int</span> max_bus_width;
+00016 int (*card_power)(<span class="keyword">struct </span>platform_device *, <span class="keyword">enum</span> <a class="code" href="group__sdriver.html#ga32">sdio_power</a>);
+00017 int (*card_present)(<span class="keyword">struct </span>platform_device *);
+00018 };
+00019
+00020 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_IMX27_LX_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__imx31_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__imx31_8h-source.html
new file mode 100644
index 0000000..c4f7b6e
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__imx31_8h-source.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx31.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx31.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * i.MX31 SDHC definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_IMX31_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_IMX31_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="comment">/*</span>
+00013 <span class="comment"> * i.MX31 SDHC registers.</span>
+00014 <span class="comment"> */</span>
+00015
+00016 <span class="preprocessor">#define SDHC_STR_STP_CLK 0x00</span>
+00017 <span class="preprocessor"></span><span class="preprocessor"># define STR_STP_CLK_MMCSD_RESET 0x0008</span>
+00018 <span class="preprocessor"></span><span class="preprocessor"># define STR_STP_CLK_START_CLK 0x0002</span>
+00019 <span class="preprocessor"></span><span class="preprocessor"># define STR_STP_CLK_STOP_CLK 0x0001</span>
+00020 <span class="preprocessor"></span>
+00021 <span class="preprocessor">#define SDHC_STATUS 0x04</span>
+00022 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CARD_PRESENCE 0x8000</span>
+00023 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_SDIO_INT_ACTIVE 0x4000</span>
+00024 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_END_CMD_RESP 0x2000</span>
+00025 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_WRITE_OP_DONE 0x1000</span>
+00026 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_READ_OP_DONE 0x0800</span>
+00027 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CARD_BUS_CLK_RUN 0x0100</span>
+00028 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_APPL_BUFF_FF 0x0080</span>
+00029 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_APPL_BUFF_FE 0x0040</span>
+00030 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_RESP_CRC_ERR 0x0020</span>
+00031 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CRC_READ_ERR 0x0008</span>
+00032 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_CRC_WRITE_ERR 0x0004</span>
+00033 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_TIME_OUT_RESP 0x0002</span>
+00034 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_TIME_OUT_READ 0x0001</span>
+00035 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP)</span>
+00036 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ)</span>
+00037 <span class="preprocessor"></span><span class="preprocessor"># define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK)</span>
+00038 <span class="preprocessor"></span>
+00039 <span class="preprocessor">#define SDHC_CLK_RATE 0x08</span>
+00040 <span class="preprocessor"></span>
+00041 <span class="preprocessor">#define SDHC_CMD_DAT_CTRL 0x0c </span><span class="comment">/* CMD_DAT_CONT */</span>
+00042 <span class="preprocessor"># define CMD_DAT_CTRL_CMD_RESUME 0x8000</span>
+00043 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000</span>
+00044 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800</span>
+00045 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_START_READ_WAIT 0x0400</span>
+00046 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200</span>
+00047 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_INIT 0x0080</span>
+00048 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_WRITE 0x0010</span>
+00049 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_DATA_ENABLE 0x0008</span>
+00050 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_NONE 0x0000</span>
+00051 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001</span>
+00052 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_R2 0x0002</span>
+00053 <span class="preprocessor"></span><span class="preprocessor"># define CMD_DAT_CTRL_RESP_R3_R4 0x0003</span>
+00054 <span class="preprocessor"></span>
+00055 <span class="preprocessor">#define SDHC_RES_TO 0x10</span>
+00056 <span class="preprocessor"></span>
+00057 <span class="preprocessor">#define SDHC_READ_TO 0x14</span>
+00058 <span class="preprocessor"></span><span class="preprocessor"># define READ_TO_RECOMMENDED 0x2db4</span>
+00059 <span class="preprocessor"></span>
+00060 <span class="preprocessor">#define SDHC_BLK_LEN 0x18</span>
+00061 <span class="preprocessor"></span>
+00062 <span class="preprocessor">#define SDHC_NOB 0x1c</span>
+00063 <span class="preprocessor"></span>
+00064 <span class="preprocessor">#define SDHC_REV_NO 0x20</span>
+00065 <span class="preprocessor"></span>
+00066 <span class="preprocessor">#define SDHC_INT_CTRL 0x24 </span><span class="comment">/* INT_CNTR */</span>
+00067 <span class="preprocessor"># define INT_CTRL_CARD_INSERTION_EN 0x8000</span>
+00068 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_SDIO_REMOVAL_EN 0x4000</span>
+00069 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_SDIO_IRQ_EN 0x2000</span>
+00070 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_DAT0_EN 0x1000</span>
+00071 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_BUF_READ_EN 0x0010</span>
+00072 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_BUF_WRITE_EN 0x0008</span>
+00073 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_END_CMD_RES 0x0004</span>
+00074 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_WRITE_OP_DONE 0x0002</span>
+00075 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_READ_OP_DONE 0x0001</span>
+00076 <span class="preprocessor"></span><span class="preprocessor"># define INT_CTRL_INT_EN_MASK 0xe01f</span>
+00077 <span class="preprocessor"></span>
+00078 <span class="preprocessor">#define SDHC_CMD 0x28</span>
+00079 <span class="preprocessor"></span>
+00080 <span class="preprocessor">#define SDHC_ARG 0x2c</span>
+00081 <span class="preprocessor"></span>
+00082 <span class="preprocessor">#define SDHC_RES_FIFO 0x34</span>
+00083 <span class="preprocessor"></span>
+00084 <span class="preprocessor">#define SDHC_BUFFER_ACCESS 0x38</span>
+00085 <span class="preprocessor"></span>
+00086 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_IMX31_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__imx31__lx_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__imx31__lx_8h-source.html
new file mode 100644
index 0000000..ac2c879
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__imx31__lx_8h-source.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx31_lx.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_imx31_lx.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Linux i.MX27 slot driver platform data definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_IMX31_LX_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_IMX31_LX_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include "sdio_layer.h"</span>
+00013
+00014 <span class="keyword">struct </span>imx_sdio_plat_data {
+00015 <span class="keywordtype">int</span> max_bus_width;
+00016 int (*card_power)(<span class="keyword">struct </span>platform_device *, <span class="keyword">enum</span> <a class="code" href="group__sdriver.html#ga32">sdio_power</a>);
+00017 int (*card_present)(<span class="keyword">struct </span>platform_device *);
+00018 };
+00019
+00020 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_IMX31_LX_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x_8h-source.html
new file mode 100644
index 0000000..20970c9
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x_8h-source.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_pxa27x.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_pxa27x.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * PXA27x MMC/SD controller definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_PXA27X_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_PXA27X_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#define PXA27X_MMC_MMCLK_BASE_FREQ 19500000</span>
+00013 <span class="preprocessor"></span><span class="preprocessor">#define PXA27X_MMC_FIFO_SIZE 32</span>
+00014 <span class="preprocessor"></span>
+00015 <span class="preprocessor">#define STOP_CLOCK (1 &lt;&lt; 0)</span>
+00016 <span class="preprocessor"></span><span class="preprocessor">#define START_CLOCK (2 &lt;&lt; 0)</span>
+00017 <span class="preprocessor"></span>
+00018 <span class="preprocessor">#define STAT_END_CMD_RES (1 &lt;&lt; 13)</span>
+00019 <span class="preprocessor"></span><span class="preprocessor">#define STAT_PRG_DONE (1 &lt;&lt; 12)</span>
+00020 <span class="preprocessor"></span><span class="preprocessor">#define STAT_DATA_TRAN_DONE (1 &lt;&lt; 11)</span>
+00021 <span class="preprocessor"></span><span class="preprocessor">#define STAT_CLK_EN (1 &lt;&lt; 8)</span>
+00022 <span class="preprocessor"></span><span class="preprocessor">#define STAT_RECV_FIFO_FULL (1 &lt;&lt; 7)</span>
+00023 <span class="preprocessor"></span><span class="preprocessor">#define STAT_XMIT_FIFO_EMPTY (1 &lt;&lt; 6)</span>
+00024 <span class="preprocessor"></span><span class="preprocessor">#define STAT_RES_CRC_ERR (1 &lt;&lt; 5)</span>
+00025 <span class="preprocessor"></span><span class="preprocessor">#define STAT_SPI_READ_ERROR_TOKEN (1 &lt;&lt; 4)</span>
+00026 <span class="preprocessor"></span><span class="preprocessor">#define STAT_CRC_READ_ERROR (1 &lt;&lt; 3)</span>
+00027 <span class="preprocessor"></span><span class="preprocessor">#define STAT_CRC_WRITE_ERROR (1 &lt;&lt; 2)</span>
+00028 <span class="preprocessor"></span><span class="preprocessor">#define STAT_TIME_OUT_RESPONSE (1 &lt;&lt; 1)</span>
+00029 <span class="preprocessor"></span><span class="preprocessor">#define STAT_READ_TIME_OUT (1 &lt;&lt; 0)</span>
+00030 <span class="preprocessor"></span>
+00031 <span class="preprocessor">#define SPI_CS_ADDRESS (1 &lt;&lt; 3)</span>
+00032 <span class="preprocessor"></span><span class="preprocessor">#define SPI_CS_EN (1 &lt;&lt; 2)</span>
+00033 <span class="preprocessor"></span><span class="preprocessor">#define CRC_ON (1 &lt;&lt; 1)</span>
+00034 <span class="preprocessor"></span><span class="preprocessor">#define SPI_EN (1 &lt;&lt; 0)</span>
+00035 <span class="preprocessor"></span>
+00036 <span class="preprocessor">#define CMDAT_SDIO_INT_EN (1 &lt;&lt; 11)</span>
+00037 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_STOP_TRAN (1 &lt;&lt; 10)</span>
+00038 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_SD_4DAT (1 &lt;&lt; 8)</span>
+00039 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_DMAEN (1 &lt;&lt; 7)</span>
+00040 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_INIT (1 &lt;&lt; 6)</span>
+00041 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_BUSY (1 &lt;&lt; 5)</span>
+00042 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_STREAM (1 &lt;&lt; 4) </span><span class="comment">/* 1 = stream */</span>
+00043 <span class="preprocessor">#define CMDAT_WRITE (1 &lt;&lt; 3) </span><span class="comment">/* 1 = write */</span>
+00044 <span class="preprocessor">#define CMDAT_DATAEN (1 &lt;&lt; 2)</span>
+00045 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_RESP_NONE (0 &lt;&lt; 0)</span>
+00046 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_RESP_SHORT (1 &lt;&lt; 0)</span>
+00047 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_RESP_R2 (2 &lt;&lt; 0)</span>
+00048 <span class="preprocessor"></span><span class="preprocessor">#define CMDAT_RESP_R3 (3 &lt;&lt; 0)</span>
+00049 <span class="preprocessor"></span>
+00050 <span class="preprocessor">#define RDTO_MAX 0xffff</span>
+00051 <span class="preprocessor"></span>
+00052 <span class="preprocessor">#define BUF_PART_FULL (1 &lt;&lt; 0)</span>
+00053 <span class="preprocessor"></span>
+00054 <span class="preprocessor">#define SDIO_SUSPEND_ACK (1 &lt;&lt; 12)</span>
+00055 <span class="preprocessor"></span><span class="preprocessor">#define SDIO_INT (1 &lt;&lt; 11)</span>
+00056 <span class="preprocessor"></span><span class="preprocessor">#define RD_STALLED (1 &lt;&lt; 10)</span>
+00057 <span class="preprocessor"></span><span class="preprocessor">#define RES_ERR (1 &lt;&lt; 9)</span>
+00058 <span class="preprocessor"></span><span class="preprocessor">#define DAT_ERR (1 &lt;&lt; 8)</span>
+00059 <span class="preprocessor"></span><span class="preprocessor">#define TINT (1 &lt;&lt; 7)</span>
+00060 <span class="preprocessor"></span><span class="preprocessor">#define TXFIFO_WR_REQ (1 &lt;&lt; 6)</span>
+00061 <span class="preprocessor"></span><span class="preprocessor">#define RXFIFO_RD_REQ (1 &lt;&lt; 5)</span>
+00062 <span class="preprocessor"></span><span class="preprocessor">#define CLK_IS_OFF (1 &lt;&lt; 4)</span>
+00063 <span class="preprocessor"></span><span class="preprocessor">#define STOP_CMD (1 &lt;&lt; 3)</span>
+00064 <span class="preprocessor"></span><span class="preprocessor">#define END_CMD_RES (1 &lt;&lt; 2)</span>
+00065 <span class="preprocessor"></span><span class="preprocessor">#define PRG_DONE (1 &lt;&lt; 1)</span>
+00066 <span class="preprocessor"></span><span class="preprocessor">#define DATA_TRAN_DONE (1 &lt;&lt; 0)</span>
+00067 <span class="preprocessor"></span>
+00068 <span class="preprocessor">#define MMC_I_MASK_ALL 0x00001fff</span>
+00069 <span class="preprocessor"></span>
+00070 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_PXA27X_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x__lx_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x__lx_8h-source.html
new file mode 100644
index 0000000..3d5d481
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__pxa27x__lx_8h-source.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_pxa27x_lx.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_pxa27x_lx.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Linux PXA27x slot driver platform data definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_PXA27X_LX_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_PXA27X_LX_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="preprocessor">#include &lt;sdioemb/slot_api.h&gt;</span>
+00013 <span class="preprocessor">#include &lt;linux/version.h&gt;</span>
+00014
+00015 <span class="preprocessor">#if LINUX_VERSION_CODE &gt;= KERNEL_VERSION(2,6,23)</span>
+00016 <span class="preprocessor"></span>
+00017 <span class="preprocessor">#define CKEN12_MMC CKEN_MMC</span>
+00018 <span class="preprocessor"></span>
+00019 <span class="preprocessor">#define MMC_STRPCL __REG(0x41100000) </span><span class="comment">/* Control to start and stop MMC clock */</span>
+00020 <span class="preprocessor">#define MMC_STAT __REG(0x41100004) </span><span class="comment">/* MMC Status Register (read only) */</span>
+00021 <span class="preprocessor">#define MMC_CLKRT __REG(0x41100008) </span><span class="comment">/* MMC clock rate */</span>
+00022 <span class="preprocessor">#define MMC_SPI __REG(0x4110000c) </span><span class="comment">/* SPI mode control bits */</span>
+00023 <span class="preprocessor">#define MMC_CMDAT __REG(0x41100010) </span><span class="comment">/* Command/response/data sequence control */</span>
+00024 <span class="preprocessor">#define MMC_RESTO __REG(0x41100014) </span><span class="comment">/* Expected response time out */</span>
+00025 <span class="preprocessor">#define MMC_RDTO __REG(0x41100018) </span><span class="comment">/* Expected data read time out */</span>
+00026 <span class="preprocessor">#define MMC_BLKLEN __REG(0x4110001c) </span><span class="comment">/* Block length of data transaction */</span>
+00027 <span class="preprocessor">#define MMC_NOB __REG(0x41100020) </span><span class="comment">/* Number of blocks, for block mode */</span>
+00028 <span class="preprocessor">#define MMC_PRTBUF __REG(0x41100024) </span><span class="comment">/* Partial MMC_TXFIFO FIFO written */</span>
+00029 <span class="preprocessor">#define MMC_I_MASK __REG(0x41100028) </span><span class="comment">/* Interrupt Mask */</span>
+00030 <span class="preprocessor">#define MMC_I_REG __REG(0x4110002c) </span><span class="comment">/* Interrupt Register (read only) */</span>
+00031 <span class="preprocessor">#define MMC_CMD __REG(0x41100030) </span><span class="comment">/* Index of current command */</span>
+00032 <span class="preprocessor">#define MMC_ARGH __REG(0x41100034) </span><span class="comment">/* MSW part of the current command argument */</span>
+00033 <span class="preprocessor">#define MMC_ARGL __REG(0x41100038) </span><span class="comment">/* LSW part of the current command argument */</span>
+00034 <span class="preprocessor">#define MMC_RES __REG(0x4110003c) </span><span class="comment">/* Response FIFO (read only) */</span>
+00035 <span class="preprocessor">#define MMC_RXFIFO __REG(0x41100040) </span><span class="comment">/* Receive FIFO (read only) */</span>
+00036 <span class="preprocessor">#define MMC_TXFIFO __REG(0x41100044) </span><span class="comment">/* Transmit FIFO (write only) */</span>
+00037
+00038 <span class="preprocessor">#endif</span>
+00039 <span class="preprocessor"></span>
+00040
+00041 <span class="keyword">struct </span>pxa27x_sdio_plat_data {
+00042 int (*card_power)(<span class="keyword">struct </span>device *, <span class="keyword">enum</span> <a class="code" href="group__sdriver.html#ga32">sdio_power</a>);
+00043 int (*card_present)(<span class="keyword">struct </span>device *);
+00044 };
+00045
+00046 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_PXA27X_LX_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__shc_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__shc_8h-source.html
new file mode 100644
index 0000000..bb14629
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__shc_8h-source.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_shc.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_shc.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Standard Host Controller definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_SHC_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_SHC_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="comment">/* SHC registers */</span>
+00013 <span class="preprocessor">#define SHC_SYSTEM_ADDRESS 0x00</span>
+00014 <span class="preprocessor"></span>
+00015 <span class="preprocessor">#define SHC_BLOCK_SIZE 0x04</span>
+00016 <span class="preprocessor"></span><span class="preprocessor"># define SHC_BLOCK_SIZE_DMA_BOUNDRY_4K 0x0000</span>
+00017 <span class="preprocessor"></span>
+00018 <span class="preprocessor">#define SHC_BLOCK_COUNT 0x06</span>
+00019 <span class="preprocessor"></span><span class="preprocessor">#define SHC_ARG 0x08</span>
+00020 <span class="preprocessor"></span>
+00021 <span class="preprocessor">#define SHC_TRANSFER_MODE 0x0c</span>
+00022 <span class="preprocessor"></span><span class="preprocessor"># define SHC_TRANSFER_MODE_DMA_EN 0x0001</span>
+00023 <span class="preprocessor"></span><span class="preprocessor"># define SHC_TRANSFER_MODE_BLK_CNT_EN 0x0002</span>
+00024 <span class="preprocessor"></span><span class="preprocessor"># define SHC_TRANSFER_MODE_AUTO_CMD12_EN 0x0004</span>
+00025 <span class="preprocessor"></span><span class="preprocessor"># define SHC_TRANSFER_MODE_DATA_READ 0x0010</span>
+00026 <span class="preprocessor"></span><span class="preprocessor"># define SHC_TRANSFER_MODE_MULTI_BLK 0x0020</span>
+00027 <span class="preprocessor"></span>
+00028 <span class="preprocessor">#define SHC_CMD 0x0e</span>
+00029 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_RESP_NONE 0x0000</span>
+00030 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_RESP_136 0x0001</span>
+00031 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_RESP_48 0x0002</span>
+00032 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_RESP_48B 0x0003</span>
+00033 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_RESP_CRC_CHK 0x0008</span>
+00034 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_RESP_IDX_CHK 0x0010</span>
+00035 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_DATA_PRESENT 0x0020</span>
+00036 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_TYPE_ABORT (0x3 &lt;&lt; 6)</span>
+00037 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CMD_IDX(c) ((c) &lt;&lt; 8)</span>
+00038 <span class="preprocessor"></span>
+00039 <span class="preprocessor">#define SHC_RESPONSE_0_31 0x10</span>
+00040 <span class="preprocessor"></span>
+00041 <span class="preprocessor">#define SHC_BUFFER_DATA_PORT 0x20</span>
+00042 <span class="preprocessor"></span>
+00043 <span class="preprocessor">#define SHC_PRESENT_STATE 0x24</span>
+00044 <span class="preprocessor"></span><span class="preprocessor"># define SHC_PRESENT_STATE_CMD_INHIBIT 0x00000001</span>
+00045 <span class="preprocessor"></span><span class="preprocessor"># define SHC_PRESENT_STATE_DAT_INHIBIT 0x00000002</span>
+00046 <span class="preprocessor"></span><span class="preprocessor"># define SHC_PRESENT_STATE_CARD_PRESENT 0x00010000</span>
+00047 <span class="preprocessor"></span>
+00048 <span class="preprocessor">#define SHC_HOST_CTRL 0x28</span>
+00049 <span class="preprocessor"></span><span class="preprocessor"># define SHC_HOST_CTRL_LED_ON 0x01</span>
+00050 <span class="preprocessor"></span><span class="preprocessor"># define SHC_HOST_CTRL_4BIT 0x02</span>
+00051 <span class="preprocessor"></span><span class="preprocessor"># define SHC_HOST_CTRL_HIGH_SPD_EN 0x04</span>
+00052 <span class="preprocessor"></span>
+00053
+00054 <span class="preprocessor">#define SHC_PWR_CTRL 0x29</span>
+00055 <span class="preprocessor"></span><span class="preprocessor"># define SHC_PWR_CTRL_3V3 0x0e</span>
+00056 <span class="preprocessor"></span><span class="preprocessor"># define SHC_PWR_CTRL_ON 0x01</span>
+00057 <span class="preprocessor"></span>
+00058 <span class="preprocessor">#define SHC_BLOCK_GAP_CTRL 0x2a</span>
+00059 <span class="preprocessor"></span><span class="preprocessor">#define SHC_WAKEUP_CTRL 0x2b</span>
+00060 <span class="preprocessor"></span>
+00061 <span class="preprocessor">#define SHC_CLOCK_CTRL 0x2c</span>
+00062 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CLOCK_CTRL_INT_CLK_EN 0x01</span>
+00063 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CLOCK_CTRL_INT_CLK_STABLE 0x02</span>
+00064 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CLOCK_CTRL_SD_CLK_EN 0x04</span>
+00065 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CLOCK_CTRL_DIV(d) (((d) &gt;&gt; 1) &lt;&lt; 8) </span><span class="comment">/* divisor must be power of 2 */</span>
+00066
+00067 <span class="preprocessor">#define SHC_TIMEOUT_CTRL 0x2e</span>
+00068 <span class="preprocessor"></span><span class="preprocessor"># define SHC_TIMEOUT_CTRL_MAX 0x0e</span>
+00069 <span class="preprocessor"></span>
+00070 <span class="preprocessor">#define SHC_SOFTWARE_RST 0x2f</span>
+00071 <span class="preprocessor"></span><span class="preprocessor"># define SHC_SOFTWARE_RST_ALL 0x01</span>
+00072 <span class="preprocessor"></span><span class="preprocessor"># define SHC_SOFTWARE_RST_CMD 0x02</span>
+00073 <span class="preprocessor"></span><span class="preprocessor"># define SHC_SOFTWARE_RST_DAT 0x04</span>
+00074 <span class="preprocessor"></span>
+00075 <span class="preprocessor">#define SHC_INT_STATUS 0x30</span>
+00076 <span class="preprocessor"></span><span class="preprocessor">#define SHC_INT_STATUS_EN 0x34</span>
+00077 <span class="preprocessor"></span><span class="preprocessor">#define SHC_INT_SIGNAL_EN 0x38</span>
+00078 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_CMD_COMPLETE 0x00000001</span>
+00079 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_TRANSFER_COMPLETE 0x00000002</span>
+00080 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_BLOCK_GAP 0x00000004</span>
+00081 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_DMA 0x00000008</span>
+00082 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_WR_BUF_RDY 0x00000010</span>
+00083 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_RD_BUF_RDY 0x00000020</span>
+00084 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_CARD_INSERTED 0x00000040</span>
+00085 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_CARD_REMOVED 0x00000080</span>
+00086 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_CARD_INT 0x00000100</span>
+00087 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_ANY 0x00008000</span>
+00088 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_CMD_TIMEOUT 0x00010000</span>
+00089 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_CMD_CRC 0x00020000</span>
+00090 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_CMD_ENDBIT 0x00040000</span>
+00091 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_CMD_INDEX 0x00080000</span>
+00092 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_CMD_ALL 0x000f0000</span>
+00093 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_DAT_TIMEOUT 0x00100000</span>
+00094 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_DAT_CRC 0x00200000</span>
+00095 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_DAT_ENDBIT 0x00400000</span>
+00096 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_DAT_ALL 0x00700000</span>
+00097 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_CURRENT_LIMIT 0x00800000</span>
+00098 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_AUTO_CMD12 0x01000000</span>
+00099 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ERR_ALL 0x01ff0000</span>
+00100 <span class="preprocessor"></span><span class="preprocessor"># define SHC_INT_ALL 0x01ff81ff</span>
+00101 <span class="preprocessor"></span>
+00102 <span class="preprocessor">#define SHC_AUTO_CMD12_STATUS 0x3c</span>
+00103 <span class="preprocessor"></span>
+00104 <span class="preprocessor">#define SHC_CAPS 0x40</span>
+00105 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CAPS_TO_BASE_CLK_FREQ(c) (((c) &amp; 0x00003f00) &gt;&gt; 8)</span>
+00106 <span class="preprocessor"></span><span class="preprocessor"># define SHC_CAPS_PWR_3V3 (1 &lt;&lt; 24)</span>
+00107 <span class="preprocessor"></span>
+00108 <span class="preprocessor">#define SHC_MAX_CURRENT_CAPS 0x4c</span>
+00109 <span class="preprocessor"></span>
+00110 <span class="comment">/* PCI configuration registers. */</span>
+00111 <span class="preprocessor">#define PCI_SHC_SLOT_INFO 0x40</span>
+00112 <span class="preprocessor"></span>
+00113 <span class="comment">/* Maximum time to wait for a software reset. */</span>
+00114 <span class="preprocessor">#define SHC_RESET_TIMEOUT_MS 100 </span><span class="comment">/* ms */</span>
+00115
+00116 <span class="comment">/* Maximum time to wait for internal clock to stabilize */</span>
+00117 <span class="preprocessor">#define SHC_INT_CLK_STABLE_TIMEOUT_MS 100</span>
+00118 <span class="preprocessor"></span>
+00119 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_SHC_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/slot__spi__lx_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/slot__spi__lx_8h-source.html
new file mode 100644
index 0000000..da91b5a
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/slot__spi__lx_8h-source.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_spi_lx.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/slot_spi_lx.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Linux sdio spi private data definitions.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef _SLOT_SPI_LX_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define _SLOT_SPI_LX_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="keyword">struct </span>sdio_spi_plat_data {
+00013 <span class="keyword">struct </span>work_struct spi_work;
+00014 <span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *slot;
+00015 int (*enable_int)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *);
+00016 int (*disable_int)(<span class="keyword">struct </span><a class="code" href="structsdio__slot.html">sdio_slot</a> *);
+00017 };
+00018
+00019 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef _SLOT_SPI_LX_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structcspi__cmd__resp.html b/unifi_hostsw_linux_147/sdioemb/html/structcspi__cmd__resp.html
new file mode 100644
index 0000000..176034b
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structcspi__cmd__resp.html
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: cspi_cmd_resp struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>cspi_cmd_resp Struct Reference</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>unsigned&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structcspi__cmd__resp.html#o0">cmd</a>: 8</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>unsigned&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structcspi__cmd__resp.html#o1">addr</a>: 24</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structcspi__cmd__resp.html#o2">val</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint8_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structcspi__cmd__resp.html#o3">response</a></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+CSPI command parameters and response.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o1" doxytag="cspi_cmd_resp::addr" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> unsigned <a class="el" href="structcspi__cmd__resp.html#o1">cspi_cmd_resp::addr</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+24 bit address. </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="cspi_cmd_resp::cmd" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> unsigned <a class="el" href="structcspi__cmd__resp.html#o0">cspi_cmd_resp::cmd</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Command octet (type, and function). </td>
+ </tr>
+</table>
+<a class="anchor" name="o3" doxytag="cspi_cmd_resp::response" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint8_t <a class="el" href="structcspi__cmd__resp.html#o3">cspi_cmd_resp::response</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Response octet. Valid iff the command has completed and (<a class="el" href="structsdio__cmd.html#o7">sdio_cmd::status</a> &amp; SDD_CMD_ERR_CMD) == 0. </td>
+ </tr>
+</table>
+<a class="anchor" name="o2" doxytag="cspi_cmd_resp::val" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t <a class="el" href="structcspi__cmd__resp.html#o2">cspi_cmd_resp::val</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Word to write or read from the card (for non-burst commands). </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structsdio__card__io__ops.html b/unifi_hostsw_linux_147/sdioemb/html/structsdio__card__io__ops.html
new file mode 100644
index 0000000..ab28389
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structsdio__card__io__ops.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_card_io_ops struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_card_io_ops Struct Reference<br>
+<small>
+[<a class="el" href="group__fdriver.html">SDIO function driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o0" doxytag="sdio_card_io_ops::read8" ></a>
+<a class="el" href="group__fdriver.html#ga0">sdio_card_io_read8_t</a>&nbsp;</td><td class="memItemRight" valign=bottom><b>read8</b></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o1" doxytag="sdio_card_io_ops::write8" ></a>
+<a class="el" href="group__fdriver.html#ga1">sdio_card_io_write8_t</a>&nbsp;</td><td class="memItemRight" valign=bottom><b>write8</b></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o2" doxytag="sdio_card_io_ops::read" ></a>
+<a class="el" href="group__fdriver.html#ga2">sdio_card_io_read_t</a>&nbsp;</td><td class="memItemRight" valign=bottom><b>read</b></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o3" doxytag="sdio_card_io_ops::write" ></a>
+<a class="el" href="group__fdriver.html#ga3">sdio_card_io_write_t</a>&nbsp;</td><td class="memItemRight" valign=bottom><b>write</b></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+The I/O operations a function driver can perform over the SDIO bus.
+<p>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd.html b/unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd.html
new file mode 100644
index 0000000..8670494
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd.html
@@ -0,0 +1,265 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_cmd struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_cmd Struct Reference<br>
+<small>
+[<a class="el" href="group__fdriver.html">SDIO function driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structsdio__dev.html">sdio_dev</a> *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o0">owner</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o1">callback</a> )(struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *cmd)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>unsigned&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o2">flags</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structsdio__cmd__resp.html">sdio_cmd_resp</a>&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o3">sdio</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structcspi__cmd__resp.html">cspi_cmd_resp</a>&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o4">cspi</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint8_t *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o5">data</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>size_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o6">len</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>enum <a class="el" href="group__fdriver.html#ga39">sdio_cmd_status</a>&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o7">status</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd.html#o8">priv</a></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+An SDIO command, its status and response.<p>
+sdio_cmd is used to submit SDIO commands to a device and return its status and any response or data.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o1" doxytag="sdio_cmd::callback" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void(* <a class="el" href="structsdio__cmd.html#o1">sdio_cmd::callback</a>)(struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *cmd)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Called by the core when the command has been completed.<p>
+Called in: interrupt context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>cmd</em>&nbsp;</td><td>the completed command. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o4" doxytag="sdio_cmd::cspi" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structcspi__cmd__resp.html">cspi_cmd_resp</a> <a class="el" href="structsdio__cmd.html#o4">sdio_cmd::cspi</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+CSPI command parameters and response.<p>
+Valid only if <a class="el" href="group__fdriver.html#ga37">SDD_CMD_FLAG_CSPI</a> is set in <a class="el" href="structsdio__cmd.html#o2">flags</a>. </td>
+ </tr>
+</table>
+<a class="anchor" name="o5" doxytag="sdio_cmd::data" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint8_t* <a class="el" href="structsdio__cmd.html#o5">sdio_cmd::data</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Buffer of data to read or write.<p>
+Must be set to NULL if the command is not a data transfer. </td>
+ </tr>
+</table>
+<a class="anchor" name="o2" doxytag="sdio_cmd::flags" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> unsigned <a class="el" href="structsdio__cmd.html#o2">sdio_cmd::flags</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set of flags specifying the response type, data transfer direction and other parameters.<p>
+For SDIO commands set at least one of the response types:<ul>
+<li><a class="el" href="group__fdriver.html#ga25">SDD_CMD_FLAG_RESP_NONE</a></li><li><a class="el" href="group__fdriver.html#ga26">SDD_CMD_FLAG_RESP_R1</a></li><li><a class="el" href="group__fdriver.html#ga27">SDD_CMD_FLAG_RESP_R1B</a></li><li><a class="el" href="group__fdriver.html#ga28">SDD_CMD_FLAG_RESP_R2</a></li><li><a class="el" href="group__fdriver.html#ga29">SDD_CMD_FLAG_RESP_R3</a></li><li><a class="el" href="group__fdriver.html#ga30">SDD_CMD_FLAG_RESP_R4</a></li><li><a class="el" href="group__fdriver.html#ga31">SDD_CMD_FLAG_RESP_R5</a></li><li><a class="el" href="group__fdriver.html#ga32">SDD_CMD_FLAG_RESP_R5B</a></li><li><a class="el" href="group__fdriver.html#ga33">SDD_CMD_FLAG_RESP_R6</a></li></ul>
+<p>
+and any of the additional flags:<ul>
+<li><a class="el" href="group__fdriver.html#ga36">SDD_CMD_FLAG_READ</a></li></ul>
+<p>
+For CSPI commands set:<ul>
+<li><a class="el" href="group__fdriver.html#ga37">SDD_CMD_FLAG_CSPI</a> </li></ul>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o6" doxytag="sdio_cmd::len" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> size_t <a class="el" href="structsdio__cmd.html#o6">sdio_cmd::len</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Length of <a class="el" href="structsdio__cmd.html#o5">data</a> in octets.<p>
+len must be either: less than the device's <a class="el" href="structsdio__dev.html#o6">sdio_dev::blocksize</a>; or a multiple of the device's <a class="el" href="structsdio__dev.html#o6">sdio_dev::blocksize</a>. </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="sdio_cmd::owner" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structsdio__dev.html">sdio_dev</a>* <a class="el" href="structsdio__cmd.html#o0">sdio_cmd::owner</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+The SDIO device which submitted the command. Set by the core. </td>
+ </tr>
+</table>
+<a class="anchor" name="o8" doxytag="sdio_cmd::priv" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void* <a class="el" href="structsdio__cmd.html#o8">sdio_cmd::priv</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Data private to caller of <a class="el" href="group__fdriver.html#ga58">sdio_start_cmd()</a>. </td>
+ </tr>
+</table>
+<a class="anchor" name="o3" doxytag="sdio_cmd::sdio" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structsdio__cmd__resp.html">sdio_cmd_resp</a> <a class="el" href="structsdio__cmd.html#o3">sdio_cmd::sdio</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+SDIO command parameters and response.<p>
+Valid only if <a class="el" href="group__fdriver.html#ga37">SDD_CMD_FLAG_CSPI</a> is <em>not</em> set in <a class="el" href="structsdio__cmd.html#o2">flags</a>. </td>
+ </tr>
+</table>
+<a class="anchor" name="o7" doxytag="sdio_cmd::status" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> enum <a class="el" href="group__fdriver.html#ga39">sdio_cmd_status</a> <a class="el" href="structsdio__cmd.html#o7">sdio_cmd::status</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Status of the command after it has completed. </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd__resp.html b/unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd__resp.html
new file mode 100644
index 0000000..0565777
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structsdio__cmd__resp.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_cmd_resp struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_cmd_resp Struct Reference</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint8_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd__resp.html#o0">cmd</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint32_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd__resp.html#o1">arg</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="unionsdio__response.html">sdio_response</a>&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__cmd__resp.html#o2">response</a></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+SDIO command parameters and response.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o1" doxytag="sdio_cmd_resp::arg" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint32_t <a class="el" href="structsdio__cmd__resp.html#o1">sdio_cmd_resp::arg</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Command argument. </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="sdio_cmd_resp::cmd" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint8_t <a class="el" href="structsdio__cmd__resp.html#o0">sdio_cmd_resp::cmd</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Command index (0 to 63). </td>
+ </tr>
+</table>
+<a class="anchor" name="o2" doxytag="sdio_cmd_resp::response" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> union <a class="el" href="unionsdio__response.html">sdio_response</a> <a class="el" href="structsdio__cmd__resp.html#o2">sdio_cmd_resp::response</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Response to the command. Valid iff the command has completed and (<a class="el" href="structsdio__cmd.html#o7">sdio_cmd::status</a> &amp; SDD_CMD_ERR_CMD) == 0. </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structsdio__dev.html b/unifi_hostsw_linux_147/sdioemb/html/structsdio__dev.html
new file mode 100644
index 0000000..cf21cd5
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structsdio__dev.html
@@ -0,0 +1,320 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_dev struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_dev Struct Reference<br>
+<small>
+[<a class="el" href="group__fdriver.html">SDIO function driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structsdio__func__driver.html">sdio_func_driver</a> *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o0">driver</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o1">vendor_id</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o2">device_id</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o3">function</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint8_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o4">interface</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o5">max_blocksize</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o6">blocksize</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structsdio__card__io__ops.html">sdio_card_io_ops</a> *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o7">io</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o8">slot_id</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o9">os_device</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>sdio_dev_priv *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o10">priv</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__dev.html#o11">drv_data</a></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+An SDIO device.<p>
+Each SDIO card will have an sdio_dev for each function.<p>
+None of the fields (except for drv_data) should be written.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o6" doxytag="sdio_dev::blocksize" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__dev.html#o6">sdio_dev::blocksize</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Blocksize in use. </td>
+ </tr>
+</table>
+<a class="anchor" name="o2" doxytag="sdio_dev::device_id" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t <a class="el" href="structsdio__dev.html#o2">sdio_dev::device_id</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Device ID of the card. </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="sdio_dev::driver" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structsdio__func__driver.html">sdio_func_driver</a>* <a class="el" href="structsdio__dev.html#o0">sdio_dev::driver</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Function driver for this device. </td>
+ </tr>
+</table>
+<a class="anchor" name="o11" doxytag="sdio_dev::drv_data" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void* <a class="el" href="structsdio__dev.html#o11">sdio_dev::drv_data</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Data private to the function driver. </td>
+ </tr>
+</table>
+<a class="anchor" name="o3" doxytag="sdio_dev::function" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__dev.html#o3">sdio_dev::function</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Function number of this device. </td>
+ </tr>
+</table>
+<a class="anchor" name="o4" doxytag="sdio_dev::interface" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint8_t <a class="el" href="structsdio__dev.html#o4">sdio_dev::interface</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+SDIO standard interface number. </td>
+ </tr>
+</table>
+<a class="anchor" name="o7" doxytag="sdio_dev::io" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structsdio__card__io__ops.html">sdio_card_io_ops</a>* <a class="el" href="structsdio__dev.html#o7">sdio_dev::io</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Card I/O operations.<p>
+<dl compact><dt><b><a class="el" href="deprecated.html#_deprecated000001">Deprecated:</a></b></dt><dd>See <a class="el" href="group__fdriver.html#card_io_ops">Card I/O Operations</a>. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o5" doxytag="sdio_dev::max_blocksize" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__dev.html#o5">sdio_dev::max_blocksize</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Maximum block size supported. </td>
+ </tr>
+</table>
+<a class="anchor" name="o9" doxytag="sdio_dev::os_device" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void* <a class="el" href="structsdio__dev.html#o9">sdio_dev::os_device</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Pointer to an OS-specific device structure. </td>
+ </tr>
+</table>
+<a class="anchor" name="o10" doxytag="sdio_dev::priv" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct sdio_dev_priv* <a class="el" href="structsdio__dev.html#o10">sdio_dev::priv</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Data private to the SDIO core. </td>
+ </tr>
+</table>
+<a class="anchor" name="o8" doxytag="sdio_dev::slot_id" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__dev.html#o8">sdio_dev::slot_id</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+ID of the slot this card is inserted into. </td>
+ </tr>
+</table>
+<a class="anchor" name="o1" doxytag="sdio_dev::vendor_id" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t <a class="el" href="structsdio__dev.html#o1">sdio_dev::vendor_id</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Vendor ID of the card. </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structsdio__func__driver.html b/unifi_hostsw_linux_147/sdioemb/html/structsdio__func__driver.html
new file mode 100644
index 0000000..074d38a
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structsdio__func__driver.html
@@ -0,0 +1,245 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_func_driver struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_func_driver Struct Reference<br>
+<small>
+[<a class="el" href="group__fdriver.html">SDIO function driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>const char *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html#o0">name</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structsdio__id__table.html">sdio_id_table</a> *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html#o1">id_table</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html#o2">probe</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html#o3">remove</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html#o4">card_int_handler</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html#o5">suspend</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__func__driver.html#o6">resume</a> )(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)</td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+A driver for an SDIO function.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o4" doxytag="sdio_func_driver::card_int_handler" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void(* <a class="el" href="structsdio__func__driver.html#o4">sdio_func_driver::card_int_handler</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Called by the core to signal an SDIO interrupt for this card occurs, if interrupts have been enabled with <a class="el" href="group__fdriver.html#ga55">sdio_enable_interrupt()</a>.<p>
+The driver's implementation should call <a class="el" href="group__fdriver.html#ga56">sdio_disable_interrupt()</a> and signal a thread (or similar) to actually handle the interrupt as no card I/O may be performed whilst in interrupt context. When the interrupt is handled, the driver should call <a class="el" href="group__fdriver.html#ga55">sdio_enable_interrupt()</a> to enable further interrupts to be signalled.<p>
+<dl compact><dt><b><a class="el" href="bug.html#_bug000003">Bug:</a></b></dt><dd>This will <em>not</em> work correctly with cards with more than one function raising an interrupt. </dd></dl>
+Called in: interrupt context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the device which may have raised the interrupt. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o1" doxytag="sdio_func_driver::id_table" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structsdio__id__table.html">sdio_id_table</a>* <a class="el" href="structsdio__func__driver.html#o1">sdio_func_driver::id_table</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+0 terminated array of functions supported by this device.<p>
+The driver may (for example) match on a number of vendor ID/device ID/function number triplets or on an SDIO standard interface. </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="sdio_func_driver::name" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> const char* <a class="el" href="structsdio__func__driver.html#o0">sdio_func_driver::name</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Driver name used in diagnostics. </td>
+ </tr>
+</table>
+<a class="anchor" name="o2" doxytag="sdio_func_driver::probe" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int(* <a class="el" href="structsdio__func__driver.html#o2">sdio_func_driver::probe</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Called by the core when an inserted card has functions which match those listed in id_table.<p>
+The driver's implementation should (if required):<p>
+<ul>
+<li>perform any additional probing</li><li>do function specific initialization</li><li>allocate and register any function/OS specific devices or interfaces.</li></ul>
+<p>
+Called in: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the newly inserted device.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o3" doxytag="sdio_func_driver::remove" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void(* <a class="el" href="structsdio__func__driver.html#o3">sdio_func_driver::remove</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Called by the core when a card is removed. This is only called if the <a class="el" href="structsdio__func__driver.html#o2">probe()</a> call succeeded.<p>
+The driver's implementation should (if required);<p>
+<ul>
+<li>do any function specific shutdown.</li><li>cleanup any data structures created/registers during <a class="el" href="structsdio__func__driver.html#o2">probe()</a>.</li></ul>
+<p>
+Called in: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the device being removed. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o6" doxytag="sdio_func_driver::resume" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void(* <a class="el" href="structsdio__func__driver.html#o6">sdio_func_driver::resume</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Called by the core to signal a resume power management event occured.<p>
+The driver's implementation should (if required) initialise the card to an operational mode and return as soon as possible. If the card has been powered off during suspend, the driver would have to initialise the card from scratch (f/w download, h/w initialisation, etc.).<p>
+Called in: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the device handler. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o5" doxytag="sdio_func_driver::suspend" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void(* <a class="el" href="structsdio__func__driver.html#o5">sdio_func_driver::suspend</a>)(struct <a class="el" href="structsdio__dev.html">sdio_dev</a> *fdev)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Called by the core to signal a suspend power management event occured.<p>
+The driver's implementation should (if required) set the card to a low power mode and return as soon as possible. After this function returns, the driver should not start any SDIO commands.<p>
+Called in: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>fdev</em>&nbsp;</td><td>the device handler. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structsdio__id__table.html b/unifi_hostsw_linux_147/sdioemb/html/structsdio__id__table.html
new file mode 100644
index 0000000..7cfc090
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structsdio__id__table.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_id_table struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_id_table Struct Reference<br>
+<small>
+[<a class="el" href="group__fdriver.html">SDIO function driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__id__table.html#o0">vendor_id</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint16_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__id__table.html#o1">device_id</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__id__table.html#o2">function</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint8_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__id__table.html#o3">interface</a></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+An entry for an SDIO device ID table.<p>
+Functions are matched to drivers using any combination of vendor ID, device ID, function number or standard interface.<p>
+Matching on <a class="el" href="structsdio__id__table.html#o2">function</a> == SDD_UIF_FUNC is reserved for the SDIO Userspace Interface driver. Card management drivers can match on <a class="el" href="structsdio__id__table.html#o2">function</a> == 0, these will be probed before any function drivers.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o1" doxytag="sdio_id_table::device_id" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t <a class="el" href="structsdio__id__table.html#o1">sdio_id_table::device_id</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Device ID to match or SDD_ANY_ID </td>
+ </tr>
+</table>
+<a class="anchor" name="o2" doxytag="sdio_id_table::function" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__id__table.html#o2">sdio_id_table::function</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Function number to match or SDD_ANY_FUNC </td>
+ </tr>
+</table>
+<a class="anchor" name="o3" doxytag="sdio_id_table::interface" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint8_t <a class="el" href="structsdio__id__table.html#o3">sdio_id_table::interface</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+SDIO standard interface to match or SDD_ANY_IFACE </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="sdio_id_table::vendor_id" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint16_t <a class="el" href="structsdio__id__table.html#o0">sdio_id_table::vendor_id</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Vendor ID to match or SDD_ANY_ID </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structsdio__slot.html b/unifi_hostsw_linux_147/sdioemb/html/structsdio__slot.html
new file mode 100644
index 0000000..35cbf33
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structsdio__slot.html
@@ -0,0 +1,519 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_slot struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_slot Struct Reference<br>
+<small>
+[<a class="el" href="group__sdriver.html">SDIO slot driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="slot__api_8h-source.html">slot_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>char&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o0">name</a> [64]</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>enum slot_controller_type&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o1">type</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o2">set_bus_freq</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, int clk)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o3">set_bus_width</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, int <a class="el" href="structsdio__slot.html#o12">bus_width</a>)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o4">start_cmd</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *cmd)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o5">card_present</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o6">card_power</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, enum <a class="el" href="group__sdriver.html#ga32">sdio_power</a> power)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o7">enable_card_int</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o8">disable_card_int</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int(*&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o9">hard_reset</a> )(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)</td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="el" href="structslot__caps.html">slot_caps</a>&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o10">caps</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o11">clock_freq</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o12">bus_width</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o13">cspi_reg_pad</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o14">cspi_burst_pad</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>sdio_slot_priv *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o15">priv</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>void *&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structsdio__slot.html#o16">drv_data</a></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+An SDIO slot driver.<p>
+Allocate and free with <a class="el" href="group__sdriver.html#ga8">sdio_slot_alloc()</a> and <a class="el" href="group__sdriver.html#ga9">sdio_slot_free()</a>.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o12" doxytag="sdio_slot::bus_width" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__slot.html#o12">sdio_slot::bus_width</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Bus width requested by the SDIO layer. </td>
+ </tr>
+</table>
+<a class="anchor" name="o10" doxytag="sdio_slot::caps" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct <a class="el" href="structslot__caps.html">slot_caps</a> <a class="el" href="structsdio__slot.html#o10">sdio_slot::caps</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Slot capabilities. </td>
+ </tr>
+</table>
+<a class="anchor" name="o6" doxytag="sdio_slot::card_power" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int(* <a class="el" href="structsdio__slot.html#o6">sdio_slot::card_power</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, enum <a class="el" href="group__sdriver.html#ga32">sdio_power</a> power)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Switch on/off the SDIO bus power and set the SDIO bus voltage.<p>
+Called from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot. </td></tr>
+ <tr><td valign=top><em>power</em>&nbsp;</td><td>the requested voltage.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success; -ve on error: -EINVAL - requested voltage is not supported. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o5" doxytag="sdio_slot::card_present" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int(* <a class="el" href="structsdio__slot.html#o5">sdio_slot::card_present</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Detect if a card is inserted into the slot.<p>
+Called from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>slot to check.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>non-zero if a card is inserted; 0 otherwise. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o11" doxytag="sdio_slot::clock_freq" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__slot.html#o11">sdio_slot::clock_freq</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+SD bus frequency requested by the SDIO layer. </td>
+ </tr>
+</table>
+<a class="anchor" name="o14" doxytag="sdio_slot::cspi_burst_pad" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__slot.html#o14">sdio_slot::cspi_burst_pad</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Padding for CSPI burst reads. </td>
+ </tr>
+</table>
+<a class="anchor" name="o13" doxytag="sdio_slot::cspi_reg_pad" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structsdio__slot.html#o13">sdio_slot::cspi_reg_pad</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Padding for CSPI register reads. </td>
+ </tr>
+</table>
+<a class="anchor" name="o8" doxytag="sdio_slot::disable_card_int" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void(* <a class="el" href="structsdio__slot.html#o8">sdio_slot::disable_card_int</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Disable (mask) the SDIO card interrupt on the controller.<p>
+Called from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot to disable the interrupt on. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o16" doxytag="sdio_slot::drv_data" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void* <a class="el" href="structsdio__slot.html#o16">sdio_slot::drv_data</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Data private to the slot driver. </td>
+ </tr>
+</table>
+<a class="anchor" name="o7" doxytag="sdio_slot::enable_card_int" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> void(* <a class="el" href="structsdio__slot.html#o7">sdio_slot::enable_card_int</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Enable (unmask) the SDIO card interrupt on the controller.<p>
+Called from: interrupt context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot to enable the interrupt on.. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o9" doxytag="sdio_slot::hard_reset" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int(* <a class="el" href="structsdio__slot.html#o9">sdio_slot::hard_reset</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Perform a hard reset of the card.<p>
+Hard resets can be achieved in two ways:<p>
+<ol>
+<li>Power cycle (if the slot has power control).</li><li>Platform-specific assertion of a card/chip reset line.</li></ol>
+<p>
+If hard resets are not supported, either return 0 or set hard_reset to NULL.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot for the card to reset.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 if a hard reset was performed. <p>
+1 if hard resets are not supported. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="sdio_slot::name" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> char <a class="el" href="structsdio__slot.html#o0">sdio_slot::name</a>[64]
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Name of the slot used in diagnostic messages.<p>
+This would typically include the name of the SDIO controller and the slot number if the controller has multiple slots. </td>
+ </tr>
+</table>
+<a class="anchor" name="o15" doxytag="sdio_slot::priv" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> struct sdio_slot_priv* <a class="el" href="structsdio__slot.html#o15">sdio_slot::priv</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Data private to the SDIO layer. </td>
+ </tr>
+</table>
+<a class="anchor" name="o2" doxytag="sdio_slot::set_bus_freq" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int(* <a class="el" href="structsdio__slot.html#o2">sdio_slot::set_bus_freq</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, int clk)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set the SD bus clock frequency.<p>
+The driver's implementation should set the SD bus clock to not more than <em>clk</em> Hz (unless <em>clk</em> is equal to #SDD_BUS_FREQ_OFF or #SDD_BUS_FREQ_IDLE).<p>
+If <em>clk</em> == SDD_BUS_FREQ_OFF the clock should be stopped.<p>
+<em>clk</em> == SDD_BUS_FREQ_IDLE indicates that the bus is idle (currently unused) and the host controller may slow (or stop) the SD bus clock to save power on the card. During this idle state the host controller must be capable of receiving SDIO interrupts (for certain host controllers this may require leaving the clock running).<p>
+If <em>clk</em> is greater than #SDIO_CLOCK_FREQ_NORMAL_SPD (25 MHz) subsequent commands should be done with the controller in high speed mode.<p>
+Called from: interrupt context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot to configure. </td></tr>
+ <tr><td valign=top><em>clk</em>&nbsp;</td><td>new SD bus clock frequency in Hz, SDD_BUS_FREQ_OFF or SDD_BUS_FREQ_IDLE.</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>The bus frequency actually configured in Hz. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o3" doxytag="sdio_slot::set_bus_width" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int(* <a class="el" href="structsdio__slot.html#o3">sdio_slot::set_bus_width</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, int <a class="el" href="structsdio__slot.html#o12">bus_width</a>)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Set the SD bus width.<p>
+The driver's implementation should set the width of the SD bus for all subsequent data transfers to the specified value.<p>
+This may be NULL if the driver sets the bus width when starting a command, or the driver is for an SDIO-SPI or CSPI controller.<p>
+Called from: thread context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>the slot to configure. </td></tr>
+ <tr><td valign=top><em>bus_width</em>&nbsp;</td><td>new SD bus width (either 1 or 4).</td></tr>
+ </table>
+</dl>
+<dl compact><dt><b>Returns:</b></dt><dd>0 on success. <p>
+-ve if a low-level error occured when setting the bus width. </dd></dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o4" doxytag="sdio_slot::start_cmd" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int(* <a class="el" href="structsdio__slot.html#o4">sdio_slot::start_cmd</a>)(struct <a class="el" href="structsdio__slot.html">sdio_slot</a> *slot, struct <a class="el" href="structsdio__cmd.html">sdio_cmd</a> *cmd)
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Start an SDIO command.<p>
+The driver's implementation should:<p>
+<ul>
+<li>set the controller's bus width to <a class="el" href="structsdio__slot.html#o12">bus_width</a>,</li><li>program the controller to start the command.</li></ul>
+<p>
+Called from: interrupt context.<p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+ <table border="0" cellspacing="2" cellpadding="0">
+ <tr><td valign=top><em>slot</em>&nbsp;</td><td>slot to perform the command. </td></tr>
+ <tr><td valign=top><em>cmd</em>&nbsp;</td><td>SDIO command to start. </td></tr>
+ </table>
+</dl>
+ </td>
+ </tr>
+</table>
+<a class="anchor" name="o1" doxytag="sdio_slot::type" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> enum slot_controller_type <a class="el" href="structsdio__slot.html#o1">sdio_slot::type</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Controller hardware type. </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="slot__api_8h-source.html">slot_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/structslot__caps.html b/unifi_hostsw_linux_147/sdioemb/html/structslot__caps.html
new file mode 100644
index 0000000..5dc4e1b
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/structslot__caps.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: slot_caps struct Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>slot_caps Struct Reference<br>
+<small>
+[<a class="el" href="group__sdriver.html">SDIO slot driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="slot__api_8h-source.html">slot_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structslot__caps.html#o0">max_bus_freq</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>int&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structslot__caps.html#o1">max_bus_width</a></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top>uint8_t&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="structslot__caps.html#o2">cspi_mode</a></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+SDIO slot capabilities.
+<p>
+<hr><h2>Field Documentation</h2>
+<a class="anchor" name="o2" doxytag="slot_caps::cspi_mode" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> uint8_t <a class="el" href="structslot__caps.html#o2">slot_caps::cspi_mode</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+CSPI_MODE register value (for CSPI capable slots). </td>
+ </tr>
+</table>
+<a class="anchor" name="o0" doxytag="slot_caps::max_bus_freq" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structslot__caps.html#o0">slot_caps::max_bus_freq</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Maximum bus frequency (Hz). </td>
+ </tr>
+</table>
+<a class="anchor" name="o1" doxytag="slot_caps::max_bus_width" ></a><p>
+<table class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+ <tr>
+ <td class="mdRow">
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="md" nowrap valign="top"> int <a class="el" href="structslot__caps.html#o1">slot_caps::max_bus_width</a>
+ </table>
+ </td>
+ </tr>
+</table>
+<table cellspacing=5 cellpadding=0 border=0>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+
+<p>
+Maximum bus width supported (1 or 4 data lines). </td>
+ </tr>
+</table>
+<hr>The documentation for this struct was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="slot__api_8h-source.html">slot_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/uif_8h-source.html b/unifi_hostsw_linux_147/sdioemb/html/uif_8h-source.html
new file mode 100644
index 0000000..e8534e7
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/uif_8h-source.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: /home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/linux/sdioemb/uif.h Source File</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/linux/sdioemb/uif.h</h1><div class="fragment"><pre>00001 <span class="comment">/*</span>
+00002 <span class="comment"> * Userspace interface to the SDIO Userspace Interface driver.</span>
+00003 <span class="comment"> *</span>
+00004 <span class="comment"> * Copyright (C) 2007 Cambridge Silicon Radio Ltd.</span>
+00005 <span class="comment"> *</span>
+00006 <span class="comment"> * Refer to LICENSE.txt included with this source code for details on</span>
+00007 <span class="comment"> * the license terms.</span>
+00008 <span class="comment"> */</span>
+00009 <span class="preprocessor">#ifndef LINUX_SDIOEMB_UIF_H</span>
+00010 <span class="preprocessor"></span><span class="preprocessor">#define LINUX_SDIOEMB_UIF_H</span>
+00011 <span class="preprocessor"></span>
+00012 <span class="keyword">enum</span> sdio_uif_cmd_type {
+00013 SDD_UIF_CMD52_READ, SDD_UIF_CMD52_WRITE,
+00014 SDD_UIF_CMD53_READ, SDD_UIF_CMD53_WRITE,
+00015 };
+00016
+00017 <span class="keyword">struct </span>sdio_uif_cmd {
+00018 <span class="keyword">enum</span> sdio_uif_cmd_type type;
+00019 <span class="keywordtype">int</span> function;
+00020 uint32_t address;
+00021 uint8_t * data;
+00022 size_t len;
+00023 <span class="keywordtype">int</span> block_size;
+00024 };
+00025
+00026 <span class="preprocessor">#define SDD_UIF_IOC_MAGIC 's'</span>
+00027 <span class="preprocessor"></span>
+00028 <span class="preprocessor">#define SDD_UIF_IOCQNUMFUNCS _IO(SDD_UIF_IOC_MAGIC, 0)</span>
+00029 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCCMD _IOWR(SDD_UIF_IOC_MAGIC, 1, struct sdio_uif_cmd)</span>
+00030 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCWAITFORINT _IO(SDD_UIF_IOC_MAGIC, 2)</span>
+00031 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCTBUSWIDTH _IO(SDD_UIF_IOC_MAGIC, 3)</span>
+00032 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCREINSERT _IO(SDD_UIF_IOC_MAGIC, 4)</span>
+00033 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCTBUSFREQ _IO(SDD_UIF_IOC_MAGIC, 5)</span>
+00034 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCQMANFID _IO(SDD_UIF_IOC_MAGIC, 6)</span>
+00035 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCQCARDID _IO(SDD_UIF_IOC_MAGIC, 7)</span>
+00036 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCQSTDIF _IO(SDD_UIF_IOC_MAGIC, 8)</span>
+00037 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCQMAXBLKSZ _IO(SDD_UIF_IOC_MAGIC, 9)</span>
+00038 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCQBLKSZ _IO(SDD_UIF_IOC_MAGIC, 10)</span>
+00039 <span class="preprocessor"></span><span class="preprocessor">#define SDD_UIF_IOCTBLKSZ _IO(SDD_UIF_IOC_MAGIC, 11)</span>
+00040 <span class="preprocessor"></span>
+00041 <span class="preprocessor">#endif </span><span class="comment">/* #ifndef LINUX_SDIOEMB_UIF_H */</span>
+</pre></div><hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/html/unionsdio__response.html b/unifi_hostsw_linux_147/sdioemb/html/unionsdio__response.html
new file mode 100644
index 0000000..d3e19cc
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/html/unionsdio__response.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
+<title>sdioemb: sdio_response union Reference</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.3.5 -->
+<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
+<h1>sdio_response Union Reference<br>
+<small>
+[<a class="el" href="group__fdriver.html">SDIO function driver API</a>]</small>
+</h1><code>#include &lt;<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a>&gt;</code>
+<p>
+<table border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br><h2>Data Fields</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o0" doxytag="sdio_response::r1" ></a>
+uint32_t&nbsp;</td><td class="memItemRight" valign=bottom><b>r1</b></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o1" doxytag="sdio_response::r4" ></a>
+uint32_t&nbsp;</td><td class="memItemRight" valign=bottom><b>r4</b></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o2" doxytag="sdio_response::r5" ></a>
+uint32_t&nbsp;</td><td class="memItemRight" valign=bottom><b>r5</b></td></tr>
+
+<tr><td class="memItemLeft" nowrap align=right valign=top><a class="anchor" name="o3" doxytag="sdio_response::r6" ></a>
+uint32_t&nbsp;</td><td class="memItemRight" valign=bottom><b>r6</b></td></tr>
+
+</table>
+<hr><a name="_details"></a><h2>Detailed Description</h2>
+A response to an SDIO command.<p>
+For R1, R4, R5, and R6 responses only the middle 32 bits of the response are stored, the leading octet (start and direction bits and command index) and trailing octet (CRC and stop bit) are discarded.<p>
+<dl compact><dt><b><a class="el" href="bug.html#_bug000001">Bug:</a></b></dt><dd>R2 and R3 responses are not used by SDIO and are not supported. </dd></dl>
+
+<p>
+<hr>The documentation for this union was generated from the following file:<ul>
+<li>/home/bfsw/host/releases/sdioemb/sdioemb-15/builds/sdioemb-15/include/sdioemb/<a class="el" href="sdio__api_8h-source.html">sdio_api.h</a></ul>
+<hr size="1"><address style="align: right;"><small>Generated on Fri Nov 21 14:14:54 2008 for sdioemb by
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border=0 >
+</a>1.3.5 </small></address>
+</body>
+</html>
diff --git a/unifi_hostsw_linux_147/sdioemb/include/linux/sdioemb/uif.h b/unifi_hostsw_linux_147/sdioemb/include/linux/sdioemb/uif.h
new file mode 100644
index 0000000..2dc4129
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/linux/sdioemb/uif.h
@@ -0,0 +1,41 @@
+/*
+ * Userspace interface to the SDIO Userspace Interface driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef LINUX_SDIOEMB_UIF_H
+#define LINUX_SDIOEMB_UIF_H
+
+enum sdio_uif_cmd_type {
+ SDD_UIF_CMD52_READ, SDD_UIF_CMD52_WRITE,
+ SDD_UIF_CMD53_READ, SDD_UIF_CMD53_WRITE,
+};
+
+struct sdio_uif_cmd {
+ enum sdio_uif_cmd_type type;
+ int function;
+ uint32_t address;
+ uint8_t * data;
+ size_t len;
+ int block_size;
+};
+
+#define SDD_UIF_IOC_MAGIC 's'
+
+#define SDD_UIF_IOCQNUMFUNCS _IO(SDD_UIF_IOC_MAGIC, 0)
+#define SDD_UIF_IOCCMD _IOWR(SDD_UIF_IOC_MAGIC, 1, struct sdio_uif_cmd)
+#define SDD_UIF_IOCWAITFORINT _IO(SDD_UIF_IOC_MAGIC, 2)
+#define SDD_UIF_IOCTBUSWIDTH _IO(SDD_UIF_IOC_MAGIC, 3)
+#define SDD_UIF_IOCREINSERT _IO(SDD_UIF_IOC_MAGIC, 4)
+#define SDD_UIF_IOCTBUSFREQ _IO(SDD_UIF_IOC_MAGIC, 5)
+#define SDD_UIF_IOCQMANFID _IO(SDD_UIF_IOC_MAGIC, 6)
+#define SDD_UIF_IOCQCARDID _IO(SDD_UIF_IOC_MAGIC, 7)
+#define SDD_UIF_IOCQSTDIF _IO(SDD_UIF_IOC_MAGIC, 8)
+#define SDD_UIF_IOCQMAXBLKSZ _IO(SDD_UIF_IOC_MAGIC, 9)
+#define SDD_UIF_IOCQBLKSZ _IO(SDD_UIF_IOC_MAGIC, 10)
+#define SDD_UIF_IOCTBLKSZ _IO(SDD_UIF_IOC_MAGIC, 11)
+
+#endif /* #ifndef LINUX_SDIOEMB_UIF_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/cspi.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/cspi.h
new file mode 100644
index 0000000..84c4269
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/cspi.h
@@ -0,0 +1,62 @@
+/*
+ * CSPI definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef SDIOEMB_CSPI_H
+#define SDIOEMB_CSPI_H
+
+/**
+ * @addtogroup sdriver
+ *@{*/
+
+#define CSPI_FUNC(f) (f)
+#define CSPI_READ 0x10
+#define CSPI_WRITE 0x20
+#define CSPI_BURST 0x40
+#define CSPI_TYPE_MASK 0x70
+
+/**
+ * CSPI_MODE function 0 register.
+ *
+ * Various CSPI mode settings.
+ *
+ * @see CSPI specification (CS-110124-SP)
+ */
+#define CSPI_MODE 0xf7
+# define CSPI_MODE_PADDED_WRITE_HDRS (1 << 7)
+# define CSPI_MODE_PADDED_READ_HDRS (1 << 6)
+/**
+ * BigEndianRegisters bit of \ref CSPI_MODE -- enable big-endian CSPI
+ * register reads and writes.
+ *
+ * @warning This bit should never be set as it's not possible to use
+ * this mode without knowledge of which registers are 8 bit and which
+ * are 16 bit.
+ */
+# define CSPI_MODE_BE_REG (1 << 5)
+# define CSPI_MODE_BE_BURST (1 << 4)
+# define CSPI_MODE_INT_ACTIVE_HIGH (1 << 3)
+# define CSPI_MODE_INT_ON_ERR (1 << 2)
+# define CSPI_MODE_LEN_FIELD_PRESENT (1 << 1)
+# define CSPI_MODE_DRV_MISO_ON_RISING_CLK (1 << 0)
+
+#define CSPI_STATUS 0xf8
+
+#define CSPI_PADDING 0xf9
+# define CSPI_PADDING_REG(p) ((p) << 0)
+# define CSPI_PADDING_BURST(p) ((p) << 4)
+
+#define CSPI_PADDING_MAX 15
+#define CSPI_PADDING_REG_DFLT 0
+#define CSPI_PADDING_BURST_DFLT 2
+
+/* cmd byte, 3 byte addr, padding, error byte, data word */
+#define CSPI_REG_TRANSFER_LEN (1 + 3 + CSPI_PADDING_MAX + 1 + 2)
+
+/*@}*/
+
+#endif /* #ifndef SDIOEMB_CSPI_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/libsdio.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/libsdio.h
new file mode 100644
index 0000000..5f3f241
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/libsdio.h
@@ -0,0 +1,388 @@
+/*
+ * SDIO Userspace Interface library.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef SDIOEMB_LIBSDIO_H
+#define SDIOEMB_LIBSDIO_H
+
+#include <stdint.h>
+
+/**
+ * \defgroup libsdio Userspace SDIO library (libsdio)
+ *
+ * \brief \e libsdio is a Linux C library for accessing SDIO cards.
+ *
+ * Use of this library requires several \e sdioemb kernel modules to be
+ * loaded:
+ * - \c sdio.
+ * - \c An SDIO slot driver (e.g., \c slot_shc for a standard PCI
+ * SDIO Host Controller).
+ * - \c sdio_uif which provides the required character devices
+ * (/dev/sdio_uif0 for the card in SDIO slot 0 etc.).
+ */
+/*@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sdio_uif;
+
+/**
+ * Handle to an opened SDIO Userspace Interface device.
+ */
+typedef struct sdio_uif *sdio_uif_t;
+
+/**
+ * Card interrupt handler function.
+ *
+ * @param uif handle to the interrupting device.
+ * @param arg data supplied by the caller of sdio_open().
+ */
+typedef void (*sdio_int_handler_t)(sdio_uif_t uif, void *arg);
+
+/**
+ * Asynchronous IO completion callback function.
+ *
+ * @param uif handle to the device that completed the IO operation.
+ * @param arg data supplied by the caller of the asynchronous IO operation.
+ * @param status status of the IO operation. 0 is success; -EIO,
+ * -EINVAL, -ETIMEDOUT etc. on an error.
+ */
+typedef void (*sdio_io_callback_t)(sdio_uif_t uif, void *arg, int status);
+
+/**
+ * Open a SDIO Userspace Interface device and (optionally) register a
+ * card interrupt handler and enable card interrupts.
+ *
+ * Card interrupts are masked before calling int_handler and are
+ * unmasked when int_handler returns (unless sdio_interrupt_mask() is
+ * called).
+ *
+ * @param dev_filename filename of the device to open.
+ * @param int_handler card interrupt handler; or NULL if no
+ * interrupt handler is required.
+ * @param arg argument to be passed to the interrupt handler.
+ *
+ * @return handle to the opened device; or NULL on error with errno
+ * set.
+ */
+sdio_uif_t sdio_open(const char *dev_filename,
+ sdio_int_handler_t int_handler, void *arg);
+
+/**
+ * Mask the SDIO interrupt.
+ *
+ * Call this in an interrupt handler to allow the processing of
+ * interrupts to be deferred until after the interrupt handler has
+ * returned.
+ *
+ * @note \e Must only be called from within the interrupt handler
+ * registered with sdio_open().
+ *
+ * @param uif device handle.
+ */
+void sdio_interrupt_mask(sdio_uif_t uif);
+
+/**
+ * Unmask the SDIO interrupt.
+ *
+ * Unmasks the SDIO interrupt if it had previously been masked with
+ * sdio_interrupt_mask().
+ *
+ * @param uif device handle.
+ */
+void sdio_interrupt_unmask(sdio_uif_t uif);
+
+/**
+ * Close an opened SDIO Userspace Interface device, freeing all
+ * associated resources.
+ *
+ * @param uif handle to the device.
+ */
+void sdio_close(sdio_uif_t uif);
+
+/**
+ * Return the number of functions the card has.
+ *
+ * @param uif device handle.
+ *
+ * @return number of card functions.
+ */
+int sdio_num_functions(sdio_uif_t uif);
+
+/**
+ * Set an SDIO bus to 1 bit or 4 bit wide mode.
+ *
+ * The CCCR bus interface control register will be read and rewritten
+ * with the new bus width.
+ *
+ * @param uif device handle.
+ * @param bus_width bus width (1 or 4).
+ *
+ * @return 0 on success; -ve on error with errno set.
+ *
+ * @note The card capabilities are \e not checked. The user should
+ * ensure 4 bit mode is not enabled on a card that does not support
+ * it.
+ */
+int sdio_set_bus_width(sdio_uif_t uif, int bus_width);
+
+/**
+ * Limit the frequency of (or stop) the SD bus clock.
+ *
+ * The frequency cannot be set greater than that supported by the card
+ * or the controller.
+ *
+ * @note Stopping the bus clock while other device drivers are
+ * executing commands may result in those commands not completing
+ * until the bus clock is restarted.
+ *
+ * @param uif device handle.
+ * @param max_freq maximum frequency (Hz) or 0 to stop the bus clock
+ * until the start of the next command.
+ */
+void sdio_set_max_bus_freq(sdio_uif_t uif, int max_freq);
+
+/**
+ * Return the card's manufacturer (vendor) ID.
+ *
+ * @param uif device handle.
+ *
+ * @return manufacturer ID.
+ */
+uint16_t sdio_manf_id(sdio_uif_t uif);
+
+/**
+ * Return the card's card (device) ID.
+ *
+ * @param uif device handle.
+ *
+ * @return card ID.
+ */
+uint16_t sdio_card_id(sdio_uif_t uif);
+
+/**
+ * Return the standard interface code for a function.
+ *
+ * @param uif device handle.
+ * @param func card function to query.
+ *
+ * @return the standard interface.
+ */
+uint8_t sdio_std_if(sdio_uif_t uif, int func);
+
+/**
+ * Return a function's maximum supported block size.
+ *
+ * @param uif device handle.
+ * @param func card function to query.
+ *
+ * @return maximum block size.
+ */
+int sdio_max_block_size(sdio_uif_t uif, int func);
+
+/**
+ * Return a function's current block size.
+ *
+ * @note This returns the driver's view of the block size and not the
+ * value in the function's block size register.
+ *
+ * @param uif device handle.
+ * @param func card function to query.
+ *
+ * @return the current block size.
+ */
+int sdio_block_size(sdio_uif_t uif, int func);
+
+/**
+ * Set a function's block size.
+ *
+ * The function's block size registers will be written if necessary.
+ *
+ * @param uif device handle.
+ * @param func function to modify.
+ * @param blksz the new block size; or 0 for the default size.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_set_block_size(sdio_uif_t uif, int func, int blksz);
+
+/**
+ * Read an 8 bit register.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register address.
+ * @param data the data read.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_read8(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data);
+
+/**
+ * Write an 8 bit register.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register address.
+ * @param data the data to write.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_write8(sdio_uif_t uif, int func, uint32_t addr, uint8_t data);
+
+/**
+ * Read a buffer from a 8 bit wide register/FIFO.
+ *
+ * The buffer read uses a fixed (not incrementing) address.
+ *
+ * \a block_size \e must be set to the value writted into \a func's
+ * I/O block size FBR register.
+ *
+ * If \a len % \a block_size == 0, a block mode transfer is used; a
+ * byte mode transfer is used if \a len < \a block_size.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register/FIFO address.
+ * @param data buffer to store the data read.
+ * @param len length of data to read.
+ * @param block_size block size to use for this transfer.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_read(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
+ size_t len, int block_size);
+
+/**
+ * Write a buffer to an 8 bit wide register/FIFO.
+ *
+ * The buffer write uses a fixed (not incrementing) address.
+ *
+ * \a block_size \e must be set to the value writted into \a func's
+ * I/O block size FBR register.
+ *
+ * If \a len % \a block_size == 0, a block mode transfer is used; a
+ * byte mode transfer is used if \a len < \a block_size.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register/FIFO address.
+ * @param data buffer of data to write.
+ * @param len length of the data to write.
+ * @param block_size block size to use for this transfer.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_write(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data,
+ size_t len, int block_size);
+
+/**
+ * Read an 8 bit register, without waiting for completion.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register address.
+ * @param data the data read.
+ * @param callback function to be called when the read completes.
+ * @param arg argument to be passed to callback.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_read8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
+ sdio_io_callback_t callback, void *arg);
+
+/**
+ * Write an 8 bit register, without waiting for completion.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register address.
+ * @param data the data to write.
+ * @param callback function to be called when the write completes.
+ * @param arg argument to be passed to callback.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_write8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t data,
+ sdio_io_callback_t callback, void *arg);
+
+/**
+ * Read a buffer from a 8 bit wide register/FIFO, without waiting for
+ * completion.
+ *
+ * The buffer read uses a fixed (not incrementing) address.
+ *
+ * \a block_size \e must be set to the value writted into \a func's
+ * I/O block size FBR register.
+ *
+ * If \a len % \a block_size == 0, a block mode transfer is used; a
+ * byte mode transfer is used if \a len < \a block_size.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register/FIFO address.
+ * @param data buffer to store the data read.
+ * @param len length of data to read.
+ * @param block_size block size to use for this transfer.
+ * @param callback function to be called when the read completes.
+ * @param arg argument to be passed to callback.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_read_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
+ size_t len, int block_size,
+ sdio_io_callback_t callback, void *arg);
+
+/**
+ * Write a buffer to an 8 bit wide register/FIFO, without waiting for
+ * completion.
+ *
+ * The buffer write uses a fixed (not incrementing) address.
+ *
+ * \a block_size \e must be set to the value writted into \a func's
+ * I/O block size FBR register.
+ *
+ * If \a len % \a block_size == 0, a block mode transfer is used; a
+ * byte mode transfer is used if \a len < \a block_size.
+ *
+ * @param uif device handle.
+ * @param func card function.
+ * @param addr register/FIFO address.
+ * @param data buffer of data to write.
+ * @param len length of the data to write.
+ * @param block_size block size to use for this transfer.
+ * @param callback function to be called when the write completes.
+ * @param arg argument to be passed to callback.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_write_async(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data,
+ size_t len, int block_size,
+ sdio_io_callback_t callback, void *arg);
+/**
+ * Force a card removal and reinsertion.
+ *
+ * This will power cycle the card if the slot hardware supports power
+ * control.
+ *
+ * @note The device handle will no longer be valid.
+ *
+ * @param uif device handle.
+ *
+ * @return 0 on success; or -ve on error with errno set.
+ */
+int sdio_reinsert_card(sdio_uif_t uif);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+/*@}*/
+
+#endif /* #ifndef SDIOEMB_LIBSDIO_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio.h
new file mode 100644
index 0000000..5e38b0f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio.h
@@ -0,0 +1,114 @@
+/*
+ * Standard SDIO definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef SDIOEMB_SDIO_H
+#define SDIOEMB_SDIO_H
+
+/* Maximum time for VDD to rise to VDD min. */
+#define SDIO_POWER_UP_TIME_MS 250
+
+/* Minimum SD bus clock a card must support (Hz). */
+#define SDIO_CLOCK_FREQ_MIN 400000
+
+/* Maximum clock frequency for normal mode (Hz).
+ *
+ * Although high speed mode should be suitable for all speeds not all
+ * controller/card combinations are capable of meeting the higher
+ * tolerances for (e.g.) clock rise/fall times. Therefore, default
+ * mode is used where possible for improved compatibility. */
+#define SDIO_CLOCK_FREQ_NORMAL_SPD 25000000
+
+/* Maximum clock frequency for high speed mode (Hz). */
+#define SDIO_CLOCK_FREQ_HIGH_SPD 50000000
+
+#define SDIO_MAX_FUNCTIONS 8 /* incl. F0 */
+
+/* Command argument format. */
+
+#define SDIO_CMD52_ARG_WRITE 0x80000000
+#define SDIO_CMD52_ARG_FUNC(f) ((f) << 28)
+#define SDIO_CMD52_ARG_ADDR(a) ((a) << 9)
+#define SDIO_CMD52_ARG_DATA(d) ((d) << 0)
+
+#define SDIO_CMD53_ARG_WRITE 0x80000000
+#define SDIO_CMD53_ARG_FUNC(f) ((f) << 28)
+#define SDIO_CMD53_ARG_BLK_MODE 0x08000000
+#define SDIO_CMD53_ARG_ADDR(a) ((a) << 9)
+#define SDIO_CMD53_ARG_CNT(c) ((c) << 0)
+
+/* Response format. */
+
+#define SDIO_R5_DATA(r) (((r) >> 0) & 0xff)
+#define SDIO_R5_OUT_OF_RANGE (1 << 8)
+#define SDIO_R5_FUNCTION_NUMBER (1 << 9)
+#define SDIO_R5_ERROR (1 << 11)
+
+/* Register offsets and bits. */
+
+#define SDIO_OCR_CARD_READY 0x80000000
+#define SDIO_OCR_NUM_FUNCS_MASK 0x70000000
+#define SDIO_OCR_NUM_FUNCS_OFFSET 28
+#define SDIO_OCR_VOLTAGE_3V3 0x00300000 /* 3.2-3.3V & 3.3-3.4V */
+
+#define SDIO_CCCR_SDIO_REV 0x00
+#define SDIO_CCCR_SD_REV 0x01
+#define SDIO_CCCR_IO_EN 0x02
+#define SDIO_CCCR_IO_READY 0x03
+#define SDIO_CCCR_INT_EN 0x04
+# define SDIO_CCCR_INT_EN_MIE 0x01
+#define SDIO_CCCR_INT_PENDING 0x05
+#define SDIO_CCCR_IO_ABORT 0x06
+#define SDIO_CCCR_BUS_IFACE_CNTL 0x07
+# define SDIO_CCCR_BUS_IFACE_CNTL_CD_R_DISABLE 0x80
+# define SDIO_CCCR_BUS_IFACE_CNTL_ECSI 0x20
+# define SDIO_CCCR_BUS_IFACE_CNTL_4BIT_BUS 0x02
+#define SDIO_CCCR_CARD_CAPS 0x08
+# define SDIO_CCCR_CARD_CAPS_LSC 0x40
+# define SDIO_CCCR_CARD_CAPS_4BLS 0x80
+#define SDIO_CCCR_CIS_PTR 0x09
+#define SDIO_CCCR_BUS_SUSPEND 0x0c
+#define SDIO_CCCR_FUNC_SEL 0x0d
+#define SDIO_CCCR_EXEC_FLAGS 0x0e
+#define SDIO_CCCR_READY_FLAGS 0x0f
+#define SDIO_CCCR_F0_BLK_SIZE 0x10
+#define SDIO_CCCR_PWR_CNTL 0x12
+#define SDIO_CCCR_HIGH_SPEED 0x13
+# define SDIO_CCCR_HIGH_SPEED_SHS 0x01
+# define SDIO_CCCR_HIGH_SPEED_EHS 0x02
+
+#define SDIO_FBR_REG(f, r) (0x100*(f) + (r))
+
+#define SDIO_FBR_STD_IFACE(f) SDIO_FBR_REG(f, 0x00)
+#define SDIO_FBR_STD_IFACE_EXT(f) SDIO_FBR_REG(f, 0x01)
+#define SDIO_FBR_CIS_PTR(f) SDIO_FBR_REG(f, 0x09)
+#define SDIO_FBR_CSA_PTR(f) SDIO_FBR_REG(f, 0x0c)
+#define SDIO_FBR_CSA_DATA(f) SDIO_FBR_REG(f, 0x0f)
+#define SDIO_FBR_BLK_SIZE(f) SDIO_FBR_REG(f, 0x10)
+
+#define SDIO_STD_IFACE_UART 0x01
+#define SDIO_STD_IFACE_BT_TYPE_A 0x02
+#define SDIO_STD_IFACE_BT_TYPE_B 0x03
+#define SDIO_STD_IFACE_GPS 0x04
+#define SDIO_STD_IFACE_CAMERA 0x05
+#define SDIO_STD_IFACE_PHS 0x06
+#define SDIO_STD_IFACE_WLAN 0x07
+
+/*
+ * Manufacturer and card IDs.
+ */
+#define SDIO_MANF_ID_CSR 0x032a
+
+#define SDIO_CARD_ID_CSR_UNIFI_1 0x0001
+#define SDIO_CARD_ID_CSR_UNIFI_2 0x0002
+#define SDIO_CARD_ID_CSR_BC6 0x0004
+#define SDIO_CARD_ID_CSR_DASH_D00 0x0005
+#define SDIO_CARD_ID_CSR_BC7 0x0006
+#define SDIO_CARD_ID_CSR_CINDERELLA 0x0007
+#define SDIO_CARD_ID_CSR_DASH 0x0010
+
+#endif /* #ifndef SDIOEMB_SDIO_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_api.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_api.h
new file mode 100644
index 0000000..35b775c
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_api.h
@@ -0,0 +1,488 @@
+/*
+ * SDIO device driver API.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SDIO_API_H
+#define _SDIO_API_H
+
+/**
+ * @defgroup fdriver SDIO function driver API
+ *
+ * @brief The SDIO function driver API is used to implement drivers
+ * for SDIO card functions.
+ *
+ * Function drivers register with the SDIO driver core
+ * (sdio_register_driver()), listing which functions it supports and
+ * providing callback functions for card inserts, removes and
+ * interrupts.
+ *
+ * @par \anchor card_io_ops Card I/O operations:
+ *
+ * - \link sdio_read8(struct sdio_dev *, uint32_t, uint8_t *) sdio_read8()\endlink
+ * - \link sdio_write8(struct sdio_dev *, uint32_t, uint8_t) sdio_write8()\endlink
+ * - \link sdio_f0_read8(struct sdio_dev *, uint32_t, uint8_t *) sdio_f0_read8()\endlink
+ * - \link sdio_f0_write8(struct sdio_dev *, uint32_t, uint8_t) sdio_f0_write8()\endlink
+ * - \link sdio_read(struct sdio_dev *, uint32_t, void *, size_t) sdio_read()\endlink
+ * - \link sdio_write(struct sdio_dev *, uint32_t, const void *, size_t) sdio_write()\endlink
+ */
+
+struct sdio_func_driver;
+struct sdio_dev;
+struct sdio_dev_priv;
+
+/**
+ * Read an 8 bit wide card register.
+ *
+ * @param fdev sdio device to read from.
+ * @param function card function number.
+ * @param addr register address.
+ * @param data returns the value read.
+ *
+ * @return 0 on success; -ve on an error:
+ * -EIO if a low-level transport error occurred (e.g., CRC error),
+ * -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+typedef int (*sdio_card_io_read8_t)(struct sdio_dev *fdev, int function,
+ uint32_t addr, uint8_t *data);
+
+/**
+ * Writes an 8 bit wide register on a card.
+ *
+ * @param fdev sdio device to write to.
+ * @param function card function number.
+ * @param addr register address.
+ * @param data value to write.
+ *
+ * @return 0 on success; -ve on an error:
+ * -EIO if a low-level transport error occurred (e.g., CRC error),
+ * -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+typedef int (*sdio_card_io_write8_t)(struct sdio_dev *fdev, int function,
+ uint32_t addr, uint8_t data);
+
+/**
+ * Read a buffer from an 8 bit wide card register/FIFO.
+ *
+ * @param fdev sdio device to read from.
+ * @param function card function number.
+ * @param addr register/FIFO address.
+ * @param data buffer to store the data read.
+ * @param len length of the buffer.
+ *
+ * @return 0 on success; -ve on an error:
+ * -EIO if a low-level transport error occurred (e.g., CRC error),
+ * -ETIMEDOUT if no response or data was received.
+ *
+ * @ingroup fdriver
+ */
+typedef int (*sdio_card_io_read_t)(struct sdio_dev *fdev, int function,
+ uint32_t addr, uint8_t *data, size_t len);
+
+/**
+ * Writes a buffer to an 8 bit wide card register/FIFO.
+ *
+ * @param fdev sdio device to write to.
+ * @param function card function number.
+ * @param addr register/FIFO address.
+ * @param data buffer of data to write.
+ * @param len length of the buffer.
+ *
+ * @return 0 on success; -ve on an error:
+ * -EIO if a low-level transport error occurred (e.g., CRC error),
+ * -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+typedef int (*sdio_card_io_write_t)(struct sdio_dev *fdev, int function,
+ uint32_t addr, const uint8_t *data, size_t len);
+
+/**
+ * The I/O operations a function driver can perform over the SDIO bus.
+ *
+ * @ingroup fdriver
+ */
+struct sdio_card_io_ops {
+ sdio_card_io_read8_t read8;
+ sdio_card_io_write8_t write8;
+ sdio_card_io_read_t read;
+ sdio_card_io_write_t write;
+};
+
+/**
+ * An SDIO device.
+ *
+ * Each SDIO card will have an sdio_dev for each function.
+ *
+ * None of the fields (except for drv_data) should be written.
+ *
+ * @ingroup fdriver
+ */
+struct sdio_dev {
+ struct sdio_func_driver *driver; /**< Function driver for this device. */
+ uint16_t vendor_id; /**< Vendor ID of the card. */
+ uint16_t device_id; /**< Device ID of the card. */
+ int function; /**< Function number of this device. */
+ uint8_t interface; /**< SDIO standard interface number. */
+ int max_blocksize; /**< Maximum block size supported. */
+ int blocksize; /**< Blocksize in use. */
+ /**
+ * Card I/O operations.
+ *
+ * @deprecated See \ref card_io_ops "Card I/O Operations".
+ */
+ struct sdio_card_io_ops *io;
+ int slot_id; /**< ID of the slot this card is inserted into. */
+ void * os_device; /**< Pointer to an OS-specific device structure. */
+ struct sdio_dev_priv * priv; /**< Data private to the SDIO core. */
+ void * drv_data; /**< Data private to the function driver. */
+};
+
+#define SDD_ANY_ID 0xffff
+#define SDD_UIF_FUNC 8
+#define SDD_ANY_FUNC 0xff
+#define SDD_ANY_IFACE 0xff
+
+/**
+ * An entry for an SDIO device ID table.
+ *
+ * Functions are matched to drivers using any combination of vendor
+ * ID, device ID, function number or standard interface.
+ *
+ * Matching on #function == SDD_UIF_FUNC is reserved for the SDIO
+ * Userspace Interface driver. Card management drivers can match on
+ * #function == 0, these will be probed before any function drivers.
+ *
+ * @ingroup fdriver
+ */
+struct sdio_id_table {
+ uint16_t vendor_id; /**< Vendor ID to match or SDD_ANY_ID */
+ uint16_t device_id; /**< Device ID to match or SDD_ANY_ID */
+ int function; /**< Function number to match or SDD_ANY_FUNC */
+ uint8_t interface; /**< SDIO standard interface to match or SDD_ANY_IFACE */
+};
+
+/**
+ * A driver for an SDIO function.
+ *
+ * @ingroup fdriver
+ */
+struct sdio_func_driver {
+ /**
+ * Driver name used in diagnostics.
+ */
+ const char *name;
+
+ /**
+ * 0 terminated array of functions supported by this device.
+ *
+ * The driver may (for example) match on a number of vendor
+ * ID/device ID/function number triplets or on an SDIO standard
+ * interface.
+ */
+ struct sdio_id_table *id_table;
+
+ /**
+ * Called by the core when an inserted card has functions which
+ * match those listed in id_table.
+ *
+ * The driver's implementation should (if required):
+ *
+ * - perform any additional probing
+ * - do function specific initialization
+ * - allocate and register any function/OS specific devices or interfaces.
+ *
+ * Called in: thread context.
+ *
+ * @param fdev the newly inserted device.
+ *
+ * @return 0 on success; -ve on error.
+ */
+ int (*probe)(struct sdio_dev *fdev);
+
+ /**
+ * Called by the core when a card is removed. This is only called
+ * if the probe() call succeeded.
+ *
+ * The driver's implementation should (if required);
+ *
+ * - do any function specific shutdown.
+ * - cleanup any data structures created/registers during probe().
+ *
+ * Called in: thread context.
+ *
+ * @param fdev the device being removed.
+ */
+ void (*remove)(struct sdio_dev *fdev);
+
+ /**
+ * Called by the core to signal an SDIO interrupt for this card
+ * occurs, if interrupts have been enabled with
+ * sdio_enable_interrupt().
+ *
+ * The driver's implementation should call
+ * sdio_disable_interrupt() and signal a thread (or similar) to
+ * actually handle the interrupt as no card I/O may be performed
+ * whilst in interrupt context. When the interrupt is handled, the
+ * driver should call sdio_enable_interrupt() to enable further
+ * interrupts to be signalled.
+ *
+ * @bug This will \e not work correctly with cards with more than
+ * one function raising an interrupt.
+ *
+ * Called in: interrupt context.
+ *
+ * @param fdev the device which may have raised the interrupt.
+ */
+ void (*card_int_handler)(struct sdio_dev *fdev);
+
+ /**
+ * Called by the core to signal a suspend power management
+ * event occured.
+ *
+ * The driver's implementation should (if required)
+ * set the card to a low power mode and return as soon
+ * as possible. After this function returns, the
+ * driver should not start any SDIO commands.
+ *
+ * Called in: thread context.
+ *
+ * @param fdev the device handler.
+ */
+ void (*suspend)(struct sdio_dev *fdev);
+
+ /**
+ * Called by the core to signal a resume power management
+ * event occured.
+ *
+ * The driver's implementation should (if required)
+ * initialise the card to an operational mode and return
+ * as soon as possible. If the card has been powered off
+ * during suspend, the driver would have to initialise
+ * the card from scratch (f/w download, h/w initialisation, etc.).
+ *
+ * Called in: thread context.
+ *
+ * @param fdev the device handler.
+ */
+ void (*resume)(struct sdio_dev *fdev);
+};
+
+int sdio_driver_register(struct sdio_func_driver *fdriver);
+void sdio_driver_unregister(struct sdio_func_driver *fdriver);
+
+/* For backward compatibility. */
+#define sdio_register_driver sdio_driver_register
+#define sdio_unregister_driver sdio_driver_unregister
+
+int sdio_set_block_size(struct sdio_dev *fdev, int blksz);
+void sdio_set_max_bus_freq(struct sdio_dev *fdev, int max_freq);
+int sdio_set_bus_width(struct sdio_dev *fdev, int bus_width);
+
+int sdio_enable_function(struct sdio_dev *fdev);
+int sdio_disable_function(struct sdio_dev *fdev);
+void sdio_idle_function(struct sdio_dev *fdev);
+
+int sdio_read8(struct sdio_dev *fdev, uint32_t addr, uint8_t *val);
+int sdio_write8(struct sdio_dev *fdev, uint32_t addr, uint8_t val);
+int sdio_f0_read8(struct sdio_dev *fdev, uint32_t addr, uint8_t *val);
+int sdio_f0_write8(struct sdio_dev *fdev, uint32_t addr, uint8_t val);
+int sdio_read(struct sdio_dev *fdev, uint32_t addr, void *data, size_t len);
+int sdio_write(struct sdio_dev *fdev, uint32_t addr, const void *data, size_t len);
+
+int sdio_hard_reset(struct sdio_dev *fdev);
+
+void sdio_power_on(struct sdio_dev *fdev);
+void sdio_power_off(struct sdio_dev *fdev);
+
+void sdio_enable_interrupt(struct sdio_dev *);
+void sdio_disable_interrupt(struct sdio_dev *);
+
+int sdio_cis_get_tuple(struct sdio_dev *fdev, uint8_t tuple,
+ void *buf, size_t len);
+
+/**
+ * SDIO command status.
+ *
+ * @ingroup fdriver
+ */
+enum sdio_cmd_status {
+ SDD_CMD_OK = 0x00, /**< Command successful. */
+
+ SDD_CMD_ERR_CMD = 0x01,
+ SDD_CMD_ERR_DAT = 0x02,
+
+ SDD_CMD_ERR_CRC = 0x10,
+ SDD_CMD_ERR_TIMEOUT = 0x20,
+ SDD_CMD_ERR_OTHER = 0x40,
+
+ SDD_CMD_ERR_CMD_CRC = SDD_CMD_ERR_CMD | SDD_CMD_ERR_CRC, /**< Response CRC error. */
+ SDD_CMD_ERR_CMD_TIMEOUT = SDD_CMD_ERR_CMD | SDD_CMD_ERR_TIMEOUT, /**< Response time out. */
+ SDD_CMD_ERR_CMD_OTHER = SDD_CMD_ERR_CMD | SDD_CMD_ERR_OTHER, /**< Other response error. */
+ SDD_CMD_ERR_DAT_CRC = SDD_CMD_ERR_DAT | SDD_CMD_ERR_CRC, /**< Data CRC error. */
+ SDD_CMD_ERR_DAT_TIMEOUT = SDD_CMD_ERR_DAT | SDD_CMD_ERR_TIMEOUT, /**< Data receive time out. */
+ SDD_CMD_ERR_DAT_OTHER = SDD_CMD_ERR_DAT | SDD_CMD_ERR_OTHER, /**< Other data error. */
+
+ SDD_CMD_ERR_NO_CARD = 0x04, /**< No card present. */
+
+ SDD_CMD_IN_PROGRESS = 0xff, /**< Command still in progress. */
+};
+
+/**
+ * A response to an SDIO command.
+ *
+ * For R1, R4, R5, and R6 responses only the middle 32 bits of the
+ * response are stored, the leading octet (start and direction bits
+ * and command index) and trailing octet (CRC and stop bit) are
+ * discarded.
+ *
+ * @bug R2 and R3 responses are not used by SDIO and are not
+ * supported.
+ *
+ * @ingroup fdriver
+ */
+union sdio_response {
+ uint32_t r1;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+};
+
+/**
+ * SDIO command parameters and response.
+ */
+struct sdio_cmd_resp {
+ uint8_t cmd; /**< Command index (0 to 63). */
+ uint32_t arg; /**< Command argument. */
+ union sdio_response response; /**< Response to the command. Valid
+ iff the command has completed and
+ (sdio_cmd::status & SDD_CMD_ERR_CMD) == 0.*/
+};
+
+/**
+ * CSPI command parameters and response.
+ */
+struct cspi_cmd_resp {
+ unsigned cmd : 8; /**< Command octet (type, and function). */
+ unsigned addr: 24; /**< 24 bit address. */
+ uint16_t val; /**< Word to write or read from the card (for non-burst commands). */
+ uint8_t response; /**< Response octet. Valid iff the command has completed and
+ (sdio_cmd::status & SDD_CMD_ERR_CMD) == 0. */
+};
+
+
+/**
+ * An SDIO command, its status and response.
+ *
+ * sdio_cmd is used to submit SDIO commands to a device and return its
+ * status and any response or data.
+ *
+ * @ingroup fdriver
+ */
+struct sdio_cmd {
+ /**
+ * The SDIO device which submitted the command. Set by the
+ * core.
+ */
+ struct sdio_dev *owner;
+
+ /**
+ * Called by the core when the command has been completed.
+ *
+ * Called in: interrupt context.
+ *
+ * @param cmd the completed command.
+ */
+ void (*callback)(struct sdio_cmd *cmd);
+
+ /**
+ * Set of flags specifying the response type, data transfer
+ * direction and other parameters.
+ *
+ * For SDIO commands set at least one of the response types:
+ * - #SDD_CMD_FLAG_RESP_NONE
+ * - #SDD_CMD_FLAG_RESP_R1
+ * - #SDD_CMD_FLAG_RESP_R1B
+ * - #SDD_CMD_FLAG_RESP_R2
+ * - #SDD_CMD_FLAG_RESP_R3
+ * - #SDD_CMD_FLAG_RESP_R4
+ * - #SDD_CMD_FLAG_RESP_R5
+ * - #SDD_CMD_FLAG_RESP_R5B
+ * - #SDD_CMD_FLAG_RESP_R6
+ *
+ * and any of the additional flags:
+ * - #SDD_CMD_FLAG_READ
+ *
+ * For CSPI commands set:
+ * - #SDD_CMD_FLAG_CSPI
+ */
+ unsigned flags;
+
+ /**
+ * SDIO command parameters and response.
+ *
+ * Valid only if #SDD_CMD_FLAG_CSPI is \e not set in #flags.
+ */
+ struct sdio_cmd_resp sdio;
+
+ /**
+ * CSPI command parameters and response.
+ *
+ * Valid only if #SDD_CMD_FLAG_CSPI is set in #flags.
+ */
+ struct cspi_cmd_resp cspi;
+
+ /**
+ * Buffer of data to read or write.
+ *
+ * Must be set to NULL if the command is not a data transfer.
+ */
+ uint8_t *data;
+
+ /**
+ * Length of #data in octets.
+ *
+ * len must be either: less than the device's sdio_dev::blocksize;
+ * or a multiple of the device's sdio_dev::blocksize.
+ */
+ size_t len;
+
+ /**
+ * Status of the command after it has completed.
+ */
+ enum sdio_cmd_status status;
+
+ /**
+ * Data private to caller of sdio_start_cmd().
+ */
+ void *priv;
+};
+
+/** @addtogroup fdriver
+ *@{*/
+#define SDD_CMD_FLAG_RESP_NONE 0x00 /**< No response. */
+#define SDD_CMD_FLAG_RESP_R1 0x01 /**< R1 response. */
+#define SDD_CMD_FLAG_RESP_R1B 0x02 /**< R1b response. */
+#define SDD_CMD_FLAG_RESP_R2 0x03 /**< R2 response. */
+#define SDD_CMD_FLAG_RESP_R3 0x04 /**< R3 response. */
+#define SDD_CMD_FLAG_RESP_R4 0x05 /**< R4 response. */
+#define SDD_CMD_FLAG_RESP_R5 0x06 /**< R5 response. */
+#define SDD_CMD_FLAG_RESP_R5B 0x07 /**< R5b response. */
+#define SDD_CMD_FLAG_RESP_R6 0x08 /**< R6 response. */
+#define SDD_CMD_FLAG_RESP_MASK 0xff /**< Mask for response type. */
+#define SDD_CMD_FLAG_RAW 0x0100 /**< @internal Bypass the command queues. */
+#define SDD_CMD_FLAG_READ 0x0200 /**< Data transfer is a read, not a write. */
+#define SDD_CMD_FLAG_CSPI 0x0400 /**< CSPI transfer, not SDIO or SDIO-SPI. */
+#define SDD_CMD_FLAG_ABORT 0x0800 /**< Data transfer abort command. */
+/*@}*/
+
+int sdio_start_cmd(struct sdio_dev *fdev, struct sdio_cmd *cmd);
+
+#endif /* #ifndef _SDIO_API_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_bt_a.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_bt_a.h
new file mode 100644
index 0000000..2c61f84
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_bt_a.h
@@ -0,0 +1,113 @@
+/*
+ * SDIO Bluetooth Type-A interface definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef SDIOEMB_SDIO_BT_A_H
+#define SDIOEMB_SDIO_BT_A_H
+
+#include <sdioemb/sdio_csr.h>
+
+/*
+ * Standard SDIO function registers for a Bluetooth Type-A interface.
+ */
+#define SDIO_BT_A_RD 0x00
+#define SDIO_BT_A_TD 0x00
+
+#define SDIO_BT_A_RX_PKT_CTRL 0x10
+# define PC_RRT 0x01
+
+#define SDIO_BT_A_TX_PKT_CTRL 0x11
+# define PC_WRT 0x01
+
+#define SDIO_BT_A_RETRY_CTRL 0x12
+# define RTC_STAT 0x01
+# define RTC_SET 0x01
+
+#define SDIO_BT_A_INTRD 0x13
+# define INTRD 0x01
+# define CL_INTRD 0x01
+
+#define SDIO_BT_A_INT_EN 0x14
+# define EN_INTRD 0x01
+
+#define SDIO_BT_A_BT_MODE 0x20
+# define MD_STAT 0x01
+
+/*
+ * Length of the Type-A header.
+ *
+ * Packet length (3 octets) plus Service ID (1 octet).
+ */
+#define SDIO_BT_A_HEADER_LEN 4
+
+/*
+ * Maximum length of a Type-A transport packet.
+ *
+ * Type-A header length and maximum length of a HCI packet (65535
+ * octets).
+ */
+#define SDIO_BT_A_PACKET_LEN_MAX 65543
+
+enum sdio_bt_a_service_id {
+ SDIO_BT_A_SID_CMD = 0x01,
+ SDIO_BT_A_SID_ACL = 0x02,
+ SDIO_BT_A_SID_SCO = 0x03,
+ SDIO_BT_A_SID_EVT = 0x04,
+ SDIO_BT_A_SID_VENDOR = 0xfe,
+};
+
+static inline int sdio_bt_a_packet_len(const char *p)
+{
+ return (p[0] & 0xff) | ((p[1] & 0xff) << 8) | ((p[2] & 0xff) << 16);
+}
+
+static inline int sdio_bt_a_service_id(const char *p)
+{
+ return p[3];
+}
+
+struct sdio_bt_a_pkt_info {
+ void * data;
+ int data_len; /* excluding Type-A header */
+ uint8_t hdr[SDIO_BT_A_HEADER_LEN];
+ uint8_t tx_data[0];
+};
+
+/*
+ * Minimum amount to read (excluding the Type-A header). This allows
+ * short packets (e.g., flow control packets) to be read with a single
+ * command.
+ */
+#define SDIO_BT_A_MIN_READ (32 - SDIO_BT_A_HEADER_LEN)
+
+#define SDIO_BT_A_NAME_LEN 16
+
+struct sdio_bt_a_dev {
+ struct sdio_dev *fdev;
+ char name[SDIO_BT_A_NAME_LEN];
+ void *drv_data;
+
+ void (*receive)(struct sdio_bt_a_dev *bt, struct sdio_bt_a_pkt_info *pkt);
+ void (*sleep_state_changed)(struct sdio_bt_a_dev *bt);
+
+ enum sdio_sleep_state sleep_state;
+
+ uint8_t max_tx_retries;
+ uint8_t max_rx_retries;
+ unsigned needs_read_ack:1;
+ unsigned wait_for_firmware:1;
+};
+
+void sdio_bt_a_init(struct sdio_bt_a_dev *bt, struct sdio_dev *fdev);
+int sdio_bt_a_send(struct sdio_bt_a_dev *bt, const struct sdio_bt_a_pkt_info *pkt);
+void sdio_bt_a_handle_interrupt(struct sdio_bt_a_dev *bt);
+void sdio_bt_a_set_sleep_state(struct sdio_bt_a_dev *bt, enum sdio_sleep_state state);
+int sdio_bt_a_check_for_reset(struct sdio_bt_a_dev *bt);
+void sdio_bt_a_start(struct sdio_bt_a_dev *bt);
+void sdio_bt_a_stop(struct sdio_bt_a_dev *bt);
+
+#endif /* #ifndef SDIOEMB_SDIO_BT_A_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_cis.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_cis.h
new file mode 100644
index 0000000..ec5e8fc
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_cis.h
@@ -0,0 +1,27 @@
+/*
+ * SDIO CIS definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SDIO_CIS_H
+#define _SDIO_CIS_H
+
+#define CISTPL_NULL 0x00
+#define CISTPL_CHECKSUM 0x10
+#define CISTPL_VERS_1 0x15
+#define CISTPL_ALTSTR 0x16
+#define CISTPL_MANFID 0x20
+# define CISTPL_MANFID_SIZE 0x04
+#define CISTPL_FUNCID 0x21
+#define CISTPL_FUNCE 0x22
+#define CISTPL_SDIO_STD 0x91
+#define CISTPL_SDIO_EXT 0x92
+#define CISTPL_END 0xff
+#define CISTPL_FUNCE 0x22
+# define CISTPL_FUNCE_00_SIZE 0x04
+# define CISTPL_FUNCE_01_SIZE 0x2a
+
+#endif /* #ifndef _SDIO_CIS_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_csr.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_csr.h
new file mode 100644
index 0000000..adc9bac
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/sdio_csr.h
@@ -0,0 +1,134 @@
+/*
+ * CSR specific SDIO registers.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef SDIOEMB_SDIO_CSR_H
+#define SDIOEMB_SDIO_CSR_H
+
+/**
+ * @defgroup registers CSR specific SDIO registers
+ *
+ * Registers at 0xF0 - 0xFF in the CCCR are reserved for vendor
+ * specific registers. The registers documented here are specific to
+ * following CSR chips:
+ *
+ * - BlueCore (6 and later)
+ * - UltraCore
+ *@{
+ */
+
+/**
+ * Interrupt status/host wakeup register.
+ *
+ * This controls a function's deep sleep state.
+ *
+ * @see enum sdio_sleep_state
+ */
+#define SDIO_CSR_SLEEP_STATE 0xf0
+# define SDIO_CSR_SLEEP_STATE_FUNC(f) ((f) << 4)
+# define SDIO_CSR_SLEEP_STATE_RDY_INT_EN 0x02
+# define SDIO_CSR_SLEEP_STATE_WAKE_REQ 0x01
+
+/**
+ * Host interrupt clear register.
+ *
+ * Writing a 1 to bit 0 clears an SDIO interrupt raised by a generic
+ * function.
+ */
+#define SDIO_CSR_HOST_INT 0xf1
+# define SDIO_CSR_HOST_INT_CL 0x01
+
+/**
+ * From host scratch register 0.
+ *
+ * A read/write register that can be used for signalling between the
+ * host and the chip.
+ *
+ * The usage of this register depends on the version of the chip or
+ * firmware.
+ */
+#define SDIO_CSR_FROM_HOST_SCRATCH0 0xf2
+
+/**
+ * From host scratch register 1.
+ *
+ * @see SDIO_CSR_FROM_HOST_SCRATCH0
+ */
+#define SDIO_CSR_FROM_HOST_SCRATCH1 0xf3
+
+/**
+ * To host scratch register 0.
+ *
+ * A read only register that may be used for signalling between the
+ * chip and the host.
+ *
+ * The usage of this register depends on the version of the chip or
+ * firmware.
+ */
+#define SDIO_CSR_TO_HOST_SCRATCH0 0xf4
+
+/**
+ * To host scratch register 1.
+ *
+ * @see SDIO_CSR_TO_HOST_SCRATCH0
+ */
+#define SDIO_CSR_TO_HOST_SCRATCH1 0xf5
+
+/**
+ * Extended I/O enable.
+ *
+ * Similar to the standard CCCR I/O Enable register, this is used to
+ * detect if an internal reset of a function has occured and
+ * (optionally) reenable it.
+ *
+ * An internal reset is detected by CCCR I/O Enable bit being set and
+ * the corresponding EXT_IO_EN bit being clear.
+ */
+#define SDIO_CSR_EXT_IO_EN 0xf6
+
+/**
+ * Deep sleep states as set via the sleep state register.
+ *
+ * These states are used to control when the chip may go into a deep
+ * sleep (a low power mode).
+ *
+ * Since a chip in deep sleep may not respond to SDIO commands, the
+ * host should ensure that the chip is not in deep sleep before
+ * attempting SDIO commands to functions 1 to 7.
+ *
+ * The available states are:
+ *
+ * AWAKE - chip must not enter deep sleep and should exit deep sleep
+ * if it's currently sleeping.
+ *
+ * TORPID - chip may enter deep sleep.
+ *
+ * DROWSY - a transition state between TORPID and AWAKE. This is
+ * AWAKE plus the chip asserts an interrupt when the chip is awake.
+ *
+ * @see SDIO_CSR_SLEEP_STATE
+ */
+enum sdio_sleep_state {
+ SLEEP_STATE_AWAKE = SDIO_CSR_SLEEP_STATE_WAKE_REQ,
+ SLEEP_STATE_DROWSY = SDIO_CSR_SLEEP_STATE_WAKE_REQ | SDIO_CSR_SLEEP_STATE_RDY_INT_EN,
+ SLEEP_STATE_TORPID = 0x00,
+};
+
+/*@}*/
+
+/*
+ * Generic function registers (with byte addresses).
+ */
+
+/*
+ * SDIO_MODE is chip dependant, see the sdio_mode table in sdio_cspi.c
+ * to add support for new chips.
+ */
+#define SDIO_MODE /* chip dependant */
+# define SDIO_MODE_CSPI_EN 0x40
+
+#endif /* SDIOEMB_SDIO_CSR_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/include/sdioemb/slot_api.h b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/slot_api.h
new file mode 100644
index 0000000..fc9d087
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/include/sdioemb/slot_api.h
@@ -0,0 +1,232 @@
+/*
+ * Slot driver API.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_API_H
+#define _SLOT_API_H
+
+#include <sdioemb/sdio_api.h>
+
+/**
+ * @defgroup sdriver SDIO slot driver API
+ *
+ * @brief The SDIO slot driver API provides an interface for the SDIO
+ * layer to driver an SDIO slot (socket).
+ *
+ * Slot drivers register with the SDIO layer (sdio_slot_register()),
+ * providing functions to starting commands, enabling/disable card
+ * interrupts, card detection and bus power control.
+ *
+ * Functions are provided to notify the SDIO layer when a command has
+ * completed (sdio_cmd_complete()) and when an SDIO card interrupt has
+ * occurred (sdio_interrupt()).
+ */
+
+#define SDD_BUS_FREQ_OFF 0
+#define SDD_BUS_FREQ_DEFAULT -1
+#define SDD_BUS_FREQ_IDLE -2
+
+/**
+ * Valid SDIO bus voltage levels.
+ *
+ * @ingroup sdriver
+ */
+enum sdio_power {
+ SDIO_POWER_OFF = 0, /**< Power switched off. */
+ SDIO_POWER_3V3 = 33, /**< Voltage set to 3.3V. */
+};
+
+/**
+ * SDIO slot capabilities.
+ *
+ * @ingroup sdriver
+ */
+struct slot_caps {
+ int max_bus_freq; /**< Maximum bus frequency (Hz). */
+ int max_bus_width; /**< Maximum bus width supported (1 or 4 data lines). */
+ uint8_t cspi_mode; /**< CSPI_MODE register value (for CSPI capable slots). */
+};
+
+/**
+ * Controller hardware type.
+ */
+enum slot_controller_type {
+ SDD_SLOT_TYPE_SD = 0, /**< SD/SDIO controller. */
+ SDD_SLOT_TYPE_SPI, /**< SPI controller. */
+ SDD_SLOT_TYPE_SPI_CSPI, /**< SPI controller capable of CSPI. */
+};
+
+struct sdio_slot_priv;
+
+/**
+ * An SDIO slot driver.
+ *
+ * Allocate and free with sdio_slot_alloc() and sdio_slot_free().
+ *
+ * @ingroup sdriver
+ */
+struct sdio_slot {
+ /**
+ * Name of the slot used in diagnostic messages.
+ *
+ * This would typically include the name of the SDIO controller
+ * and the slot number if the controller has multiple slots.
+ */
+ char name[64];
+
+ /**
+ * Controller hardware type.
+ */
+ enum slot_controller_type type;
+
+ /**
+ * Set the SD bus clock frequency.
+ *
+ * The driver's implementation should set the SD bus clock to not
+ * more than \a clk Hz (unless \a clk is equal to
+ * #SDD_BUS_FREQ_OFF or #SDD_BUS_FREQ_IDLE).
+ *
+ * If \a clk == SDD_BUS_FREQ_OFF the clock should be stopped.
+ *
+ * \a clk == SDD_BUS_FREQ_IDLE indicates that the bus is idle
+ * (currently unused) and the host controller may slow (or stop)
+ * the SD bus clock to save power on the card. During this idle
+ * state the host controller must be capable of receiving SDIO
+ * interrupts (for certain host controllers this may require
+ * leaving the clock running).
+ *
+ * If \a clk is greater than #SDIO_CLOCK_FREQ_NORMAL_SPD (25 MHz)
+ * subsequent commands should be done with the controller in high
+ * speed mode.
+ *
+ * Called from: interrupt context.
+ *
+ * @param slot the slot to configure.
+ * @param clk new SD bus clock frequency in Hz, SDD_BUS_FREQ_OFF
+ * or SDD_BUS_FREQ_IDLE.
+ *
+ * @return The bus frequency actually configured in Hz.
+ */
+ int (*set_bus_freq)(struct sdio_slot *slot, int clk);
+
+ /**
+ * Set the SD bus width.
+ *
+ * The driver's implementation should set the width of the SD bus
+ * for all subsequent data transfers to the specified value.
+ *
+ * This may be NULL if the driver sets the bus width when starting
+ * a command, or the driver is for an SDIO-SPI or CSPI controller.
+ *
+ * Called from: thread context.
+ *
+ * @param slot the slot to configure.
+ * @param bus_width new SD bus width (either 1 or 4).
+ *
+ * @return 0 on success.
+ * @return -ve if a low-level error occured when setting the bus width.
+ */
+ int (*set_bus_width)(struct sdio_slot *slot, int bus_width);
+
+ /**
+ * Start an SDIO command.
+ *
+ * The driver's implementation should:
+ *
+ * - set the controller's bus width to #bus_width,
+ * - program the controller to start the command.
+ *
+ * Called from: interrupt context.
+ *
+ * @param slot slot to perform the command.
+ * @param cmd SDIO command to start.
+ */
+ int (*start_cmd)(struct sdio_slot *slot, struct sdio_cmd *cmd);
+
+ /**
+ * Detect if a card is inserted into the slot.
+ *
+ * Called from: thread context.
+ *
+ * @param slot slot to check.
+ *
+ * @return non-zero if a card is inserted; 0 otherwise.
+ */
+ int (*card_present)(struct sdio_slot *slot);
+
+ /**
+ * Switch on/off the SDIO bus power and set the SDIO bus voltage.
+ *
+ * Called from: thread context.
+ *
+ * @param slot the slot.
+ * @param power the requested voltage.
+ *
+ * @return 0 on success; -ve on error: -EINVAL - requested voltage
+ * is not supported.
+ */
+ int (*card_power)(struct sdio_slot *slot, enum sdio_power power);
+
+ /**
+ * Enable (unmask) the SDIO card interrupt on the controller.
+ *
+ * Called from: interrupt context.
+ *
+ * @param slot the slot to enable the interrupt on..
+ */
+ void (*enable_card_int)(struct sdio_slot *slot);
+
+ /**
+ * Disable (mask) the SDIO card interrupt on the controller.
+ *
+ * Called from: thread context.
+ *
+ * @param slot the slot to disable the interrupt on.
+ */
+ void (*disable_card_int)(struct sdio_slot *slot);
+
+ /**
+ * Perform a hard reset of the card.
+ *
+ * Hard resets can be achieved in two ways:
+ *
+ * -# Power cycle (if the slot has power control).
+ * -# Platform-specific assertion of a card/chip reset line.
+ *
+ * If hard resets are not supported, either return 0 or set
+ * hard_reset to NULL.
+ *
+ * @param slot the slot for the card to reset.
+ *
+ * @return 0 if a hard reset was performed.
+ * @return 1 if hard resets are not supported.
+ */
+ int (*hard_reset)(struct sdio_slot *slot);
+
+ struct slot_caps caps; /**< Slot capabilities. */
+ int clock_freq; /**< SD bus frequency requested by the SDIO layer. */
+ int bus_width; /**< Bus width requested by the SDIO layer. */
+ int cspi_reg_pad; /**< Padding for CSPI register reads. */
+ int cspi_burst_pad; /**< Padding for CSPI burst reads. */
+ struct sdio_slot_priv *priv; /**< Data private to the SDIO layer. */
+ void * drv_data; /**< Data private to the slot driver. */
+};
+
+struct sdio_slot *sdio_slot_alloc(size_t drv_data_size);
+void sdio_slot_free(struct sdio_slot *slot);
+int sdio_slot_register(struct sdio_slot *slot);
+void sdio_slot_unregister(struct sdio_slot *slot);
+void sdio_card_inserted(struct sdio_slot *slot);
+void sdio_card_removed(struct sdio_slot *slot);
+void sdio_interrupt(struct sdio_slot *slot);
+void sdio_cmd_complete(struct sdio_slot *slot, struct sdio_cmd *cmd);
+
+void sdio_suspend(struct sdio_slot *slot);
+void sdio_resume(struct sdio_slot *slot);
+
+
+#endif /* #ifndef _SLOT_API_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/libsdio/Makefile b/unifi_hostsw_linux_147/sdioemb/libsdio/Makefile
new file mode 100644
index 0000000..acc6863
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/libsdio/Makefile
@@ -0,0 +1,35 @@
+CC := $(CROSS_COMPILE)gcc
+AR := $(CROSS_COMPILE)ar
+
+CFLAGS := -Wall -g -O2 -I../include
+LDFLAGS := -g
+LDLIBS := -L. -lsdio -lpthread
+
+%.a: %.o
+ $(AR) r $@ $^
+
+%.o: %.c
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+all: libsdio.a
+
+libsdio.a: libsdio.o libsdio_async.o
+
+libsdio.o: libsdio.c libsdio_internal.h \
+ ../include/sdioemb/libsdio.h ../include/linux/sdioemb/uif.h
+
+libsdio_async.o: libsdio_async.c libsdio_internal.h \
+ ../include/sdioemb/libsdio.h ../include/linux/sdioemb/uif.h
+
+install:
+ install -m 0644 -D libsdio.a \
+ $(DESTDIR)$(prefix)/lib/libsdio.a
+ install -m 0644 -D ../include/sdioemb/sdio.h \
+ $(DESTDIR)$(prefix)/include/sdioemb/sdio.h
+ install -m 0644 -D ../include/sdioemb/sdio_csr.h \
+ $(DESTDIR)$(prefix)/include/sdioemb/sdio_csr.h
+ install -m 0644 -D ../include/sdioemb/libsdio.h \
+ $(DESTDIR)$(prefix)/include/sdioemb/libsdio.h
+
+clean:
+ rm -f *.o libsdio.a
diff --git a/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio.c b/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio.c
new file mode 100644
index 0000000..3fae4da
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio.c
@@ -0,0 +1,236 @@
+/*
+ * SDIO Userspace Interface library.
+ *
+ * Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include <linux/sdioemb/uif.h>
+#include <sdioemb/libsdio.h>
+
+#include "libsdio_internal.h"
+
+static void *int_thread_func(void *arg);
+
+sdio_uif_t sdio_open(const char *dev_filename,
+ void (*int_handler)(struct sdio_uif *, void *), void *arg)
+{
+ struct sdio_uif *uif;
+ int ret;
+
+ uif = malloc(sizeof(struct sdio_uif));
+ if (!uif)
+ return NULL;
+
+ uif->int_handler = int_handler;
+ uif->arg = arg;
+
+ pthread_mutex_init(&uif->mutex, NULL);
+ pthread_cond_init(&uif->int_cond, NULL);
+ uif->int_masked = 0;
+
+ uif->fd = open(dev_filename, O_RDWR);
+ if (uif->fd < 0) {
+ free(uif);
+ return NULL;
+ }
+
+ ret = async_thread_start(uif);
+ if (ret < 0) {
+ free(uif);
+ return NULL;
+ }
+
+ if (uif->int_handler) {
+ int ret = pthread_create(&uif->int_thread, NULL, int_thread_func, uif);
+ if (ret) {
+ close(uif->fd);
+ free(uif);
+ return NULL;
+ }
+ }
+
+ return uif;
+}
+
+
+void sdio_close(sdio_uif_t uif)
+{
+ if (uif == NULL) {
+ return;
+ }
+ if (uif->int_handler) {
+ pthread_cancel(uif->int_thread);
+ pthread_join(uif->int_thread, NULL);
+ }
+ async_thread_stop(uif);
+ close(uif->fd);
+ pthread_mutex_destroy(&uif->mutex);
+ pthread_cond_destroy(&uif->int_cond);
+ free(uif);
+}
+
+int sdio_num_functions(sdio_uif_t uif)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCQNUMFUNCS, 0);
+}
+
+int sdio_set_bus_width(sdio_uif_t uif, int bus_width)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCTBUSWIDTH, bus_width);
+}
+
+void sdio_set_max_bus_freq(sdio_uif_t uif, int max_freq)
+{
+ ioctl(uif->fd, SDD_UIF_IOCTBUSFREQ, max_freq);
+}
+
+uint16_t sdio_manf_id(sdio_uif_t uif)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCQMANFID, 0);
+}
+
+uint16_t sdio_card_id(sdio_uif_t uif)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCQCARDID, 0);
+}
+
+uint8_t sdio_std_if(sdio_uif_t uif, int func)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCQSTDIF, func);
+}
+
+int sdio_max_block_size(sdio_uif_t uif, int func)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCQMAXBLKSZ, func);
+}
+
+int sdio_block_size(sdio_uif_t uif, int func)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCQBLKSZ, func);
+}
+
+int sdio_set_block_size(sdio_uif_t uif, int func, int blksz)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCTBLKSZ, (blksz << 8) | func);
+}
+
+int sdio_read8(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data)
+{
+ struct sdio_uif_cmd cmd;
+
+ cmd.type = SDD_UIF_CMD52_READ;
+ cmd.function = func;
+ cmd.address = addr;
+ cmd.data = data;
+ cmd.len = 1;
+
+ return ioctl(uif->fd, SDD_UIF_IOCCMD, &cmd);
+}
+
+int sdio_write8(sdio_uif_t uif, int func, uint32_t addr, uint8_t data)
+{
+ struct sdio_uif_cmd cmd;
+
+ cmd.type = SDD_UIF_CMD52_WRITE;
+ cmd.function = func;
+ cmd.address = addr;
+ cmd.data = &data;
+ cmd.len = 1;
+
+ return ioctl(uif->fd, SDD_UIF_IOCCMD, &cmd);
+}
+
+int sdio_read(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
+ size_t len, int block_size)
+{
+ struct sdio_uif_cmd cmd;
+
+ cmd.type = SDD_UIF_CMD53_READ;
+ cmd.function = func;
+ cmd.address = addr;
+ cmd.data = data;
+ cmd.len = len;
+ cmd.block_size = block_size;
+
+ return ioctl(uif->fd, SDD_UIF_IOCCMD, &cmd);
+}
+
+int sdio_write(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data,
+ size_t len, int block_size)
+{
+ struct sdio_uif_cmd cmd;
+
+ cmd.type = SDD_UIF_CMD53_WRITE;
+ cmd.function = func;
+ cmd.address = addr;
+ cmd.data = (uint8_t *)data; /* const cast is safe */
+ cmd.len = len;
+ cmd.block_size = block_size;
+
+ return ioctl(uif->fd, SDD_UIF_IOCCMD, &cmd);
+}
+
+int sdio_reinsert_card(sdio_uif_t uif)
+{
+ return ioctl(uif->fd, SDD_UIF_IOCREINSERT, 0);
+}
+
+static void *int_thread_func(void *arg)
+{
+ struct sdio_uif *uif = arg;
+
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+ for(;;) {
+ int ret = ioctl(uif->fd, SDD_UIF_IOCWAITFORINT, 0);
+ if (ret < 0) {
+ pthread_testcancel();
+ if (errno != EINTR) {
+ perror("ioctl: SDD_UIF_IOCWAITFORINT: ");
+ pthread_exit(0);
+ }
+ } else {
+ uif->int_handler(uif, uif->arg);
+ }
+
+ pthread_mutex_lock(&uif->mutex);
+ while (uif->int_masked) {
+ pthread_cond_wait(&uif->int_cond, &uif->mutex);
+ }
+ pthread_mutex_unlock(&uif->mutex);
+ }
+ pthread_exit(0);
+}
+
+void sdio_interrupt_mask(sdio_uif_t uif)
+{
+ /* mask is only callable from the interrupt handler */
+ assert(pthread_self() == uif->int_thread);
+
+ pthread_mutex_lock(&uif->mutex);
+ uif->int_masked = 1;
+ pthread_mutex_unlock(&uif->mutex);
+}
+
+void sdio_interrupt_unmask(sdio_uif_t uif)
+{
+ pthread_mutex_lock(&uif->mutex);
+ uif->int_masked = 0;
+ pthread_mutex_unlock(&uif->mutex);
+
+ pthread_cond_signal(&uif->int_cond);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_async.c b/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_async.c
new file mode 100644
index 0000000..8597c95
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_async.c
@@ -0,0 +1,165 @@
+/*
+ * libsdio asynchronous I/O functions.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include <linux/sdioemb/uif.h>
+#include <sdioemb/libsdio.h>
+
+#include "libsdio_internal.h"
+
+static void *async_thread_func(void *arg);
+
+int async_thread_start(sdio_uif_t uif)
+{
+ int ret;
+
+ pthread_cond_init(&uif->cmd_queue.cond, NULL);
+
+ uif->cmd_queue.head = NULL;
+ uif->cmd_queue.tail = NULL;
+
+ ret = pthread_create(&uif->async_thread, NULL, async_thread_func, uif);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+void async_thread_stop(sdio_uif_t uif)
+{
+ struct cmd_queue_elem *elem;
+
+ pthread_mutex_lock(&uif->mutex);
+ elem = uif->cmd_queue.head;
+ while (elem) {
+ struct cmd_queue_elem *next = elem->next;
+ free(elem);
+ elem = next;
+ }
+ pthread_mutex_unlock(&uif->mutex);
+
+ pthread_cancel(uif->async_thread);
+ pthread_join(uif->async_thread, NULL);
+}
+
+static int cmd_queue_push(sdio_uif_t uif, enum sdio_uif_cmd_type type, int func, uint32_t addr,
+ const uint8_t *data, size_t len, int block_size,
+ sdio_io_callback_t callback, void *arg)
+{
+ struct cmd_queue_elem *elem;
+
+ elem = malloc(sizeof(struct cmd_queue_elem));
+ if (elem == NULL) {
+ return -1;
+ }
+
+ elem->callback = callback;
+ elem->arg = arg;
+
+ if (type == SDD_UIF_CMD52_WRITE) {
+ elem->write8_data = *data;
+ data = &elem->write8_data;
+ }
+
+ elem->cmd.type = type;
+ elem->cmd.function = func;
+ elem->cmd.address = addr;
+ elem->cmd.data = (uint8_t *)data; /* const cast is safe */
+ elem->cmd.len = len;
+ elem->cmd.block_size = block_size;
+
+ pthread_mutex_lock(&uif->mutex);
+ elem->next = NULL;
+ if (uif->cmd_queue.tail != NULL) {
+ uif->cmd_queue.tail->next = elem;
+ }
+ if (uif->cmd_queue.head == NULL) {
+ uif->cmd_queue.head = elem;
+ }
+ uif->cmd_queue.tail = elem;
+ pthread_mutex_unlock(&uif->mutex);
+ pthread_cond_signal(&uif->cmd_queue.cond);
+
+ return 0;
+}
+
+static struct cmd_queue_elem *cmd_queue_pop(sdio_uif_t uif)
+{
+ struct cmd_queue_elem *elem;
+
+ pthread_mutex_lock(&uif->mutex);
+ while (uif->cmd_queue.head == NULL) {
+ pthread_cond_wait(&uif->cmd_queue.cond, &uif->mutex);
+ }
+
+ elem = uif->cmd_queue.head;
+ uif->cmd_queue.head = NULL;
+ if (uif->cmd_queue.head == NULL) {
+ uif->cmd_queue.tail = NULL;
+ }
+ pthread_mutex_unlock(&uif->mutex);
+
+ return elem;
+}
+
+static void *async_thread_func(void *arg)
+{
+ struct sdio_uif *uif = arg;
+
+ for (;;) {
+ struct cmd_queue_elem *elem;
+ int ret;
+
+ elem = cmd_queue_pop(uif);
+ ret = ioctl(uif->fd, SDD_UIF_IOCCMD, &elem->cmd);
+ pthread_testcancel();
+ elem->callback(uif, elem->arg, ret);
+ }
+
+ pthread_exit(0);
+}
+
+int sdio_read8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
+ sdio_io_callback_t callback, void *arg)
+{
+ return cmd_queue_push(uif, SDD_UIF_CMD52_READ, func, addr, data, 1, 0, callback, arg);
+}
+
+int sdio_write8_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t data,
+ sdio_io_callback_t callback, void *arg)
+{
+ return cmd_queue_push(uif, SDD_UIF_CMD52_WRITE, func, addr, &data, 1, 0, callback, arg);
+}
+
+int sdio_read_async(sdio_uif_t uif, int func, uint32_t addr, uint8_t *data,
+ size_t len, int block_size,
+ sdio_io_callback_t callback, void *arg)
+{
+ return cmd_queue_push(uif, SDD_UIF_CMD53_READ, func, addr, data, len, block_size,
+ callback, arg);
+}
+
+int sdio_write_async(sdio_uif_t uif, int func, uint32_t addr, const uint8_t *data,
+ size_t len, int block_size,
+ sdio_io_callback_t callback, void *arg)
+{
+ return cmd_queue_push(uif, SDD_UIF_CMD53_WRITE, func, addr, data, len, block_size,
+ callback, arg);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_internal.h b/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_internal.h
new file mode 100644
index 0000000..7dbf003
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/libsdio/libsdio_internal.h
@@ -0,0 +1,42 @@
+/*
+ * libsdio internal header.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef LIBSDIO_INTERNAL_H
+#define LIBSDIO_INTERNAL_H
+
+struct cmd_queue_elem {
+ struct cmd_queue_elem *next;
+ sdio_io_callback_t callback;
+ void *arg;
+ struct sdio_uif_cmd cmd;
+ uint8_t write8_data;
+};
+
+struct cmd_queue {
+ struct cmd_queue_elem *head;
+ struct cmd_queue_elem *tail;
+ pthread_cond_t cond;
+};
+
+struct sdio_uif {
+ void (*int_handler)(struct sdio_uif *, void *);
+ void *arg;
+ int fd;
+ pthread_t int_thread;
+ pthread_mutex_t mutex;
+ pthread_cond_t int_cond;
+ int int_masked;
+
+ struct cmd_queue cmd_queue;
+ pthread_t async_thread;
+};
+
+int async_thread_start(sdio_uif_t uif);
+void async_thread_stop(sdio_uif_t uif);
+
+#endif /* #ifndef LIBSDIO_INTERNAL_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/scripts/lndir b/unifi_hostsw_linux_147/sdioemb/scripts/lndir
new file mode 100755
index 0000000..a746156
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/scripts/lndir
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+
+canon() {
+ DIR=`dirname $1`
+ BASE=`basename $1`
+ CURDIR=`pwd`
+ cd $DIR
+ CANONDIR=`pwd`
+ cd $CURDIR
+ echo "$CANONDIR/$BASE"
+}
+
+lndir() {
+ FIND=`echo $1 | sed -e 's,/\\+,/,g'`
+ for d in `find $FIND -type d`; do
+ MODE=`stat -c %a $d`
+ NEW=`echo $d | sed -e "s,$FIND/*,,"`
+ test -n "$NEW" && mkdir -m $MODE $NEW
+ done
+ for f in `find $FIND -type f`; do
+ NEW=`echo $f | sed -e "s,$FIND/*,,"`
+ if test -n "$NEW"; then
+ OLD=`canon $f`
+ ln -s $OLD $NEW
+ fi
+ done
+}
+
+
+usage() {
+ echo "lndir <dir>"
+ echo "This is a sort-of-replacement for lndir using the shell and"
+ echo "standard shell commands. It makes a symlinked copy of the given"
+}
+
+test -z "$1" && usage && exit 1
+test -n "$2" && usage && exit 1
+lndir $1
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_card.c b/unifi_hostsw_linux_147/sdioemb/sdio_card.c
new file mode 100644
index 0000000..f690599
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_card.c
@@ -0,0 +1,548 @@
+/*
+ * Card detection and initialization.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <sdioemb/sdio_cis.h>
+
+#include "sdio_layer.h"
+#include "sdio_config.h"
+
+static struct sdio_card_io_ops sdio_io_ops = {
+ sdio_io_read8,
+ sdio_io_write8,
+ sdio_io_read,
+ sdio_io_write,
+};
+
+static int sdio_card_init_sequence(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int ret;
+ union sdio_response response;
+ uint32_t ocr, rca;
+ int timeout;
+
+ /* CMD0. Needed to start some cards. */
+ ret = sdio_raw_cmd(slot, 0, 0, SDD_CMD_FLAG_RESP_NONE, &response);
+ if (ret)
+ goto cmd_error;
+
+ /* CMD5. Read OCR. */
+ ret = sdio_raw_cmd(slot, 5, 0, SDD_CMD_FLAG_RESP_R4, &response);
+ if (ret)
+ goto cmd_error;
+ ocr = response.r4;
+ if (!(ocr & SDIO_OCR_VOLTAGE_3V3)) {
+ slot_error(slot, "card does not support 3.3V");
+ goto fatal_card_error;
+ }
+ slotp->num_functions = (ocr & SDIO_OCR_NUM_FUNCS_MASK) >> SDIO_OCR_NUM_FUNCS_OFFSET;
+
+ /* CMD5. Set operating voltage to 3.3V and wait for card to be
+ * ready. */
+ for (timeout = SDD_CARD_READY_TIMEOUT_MS; timeout > 0; timeout--) {
+ ret = sdio_raw_cmd(slot, 5, SDIO_OCR_VOLTAGE_3V3, SDD_CMD_FLAG_RESP_R4, &response);
+ if (ret) {
+ goto cmd_error;
+ }
+ ocr = response.r4;
+ if (ocr & SDIO_OCR_CARD_READY) {
+ break;
+ }
+ os_sleep_ms(1);
+ }
+ if (timeout == 0) {
+ slot_error(slot, "card not ready");
+ goto fatal_card_error;
+ }
+
+ if (slot->type == SDD_SLOT_TYPE_SD) {
+ /* CMD3. Set/read RCA. */
+ ret = sdio_raw_cmd(slot, 3, 0, SDD_CMD_FLAG_RESP_R6, &response);
+ if (ret)
+ goto cmd_error;
+ rca = response.r6 & 0xffff0000;
+
+ /* CMD7. Select card. */
+ ret = sdio_raw_cmd(slot, 7, rca, SDD_CMD_FLAG_RESP_R1B, &response);
+ if (ret)
+ goto cmd_error;
+ }
+
+ /* Successful card initialization. */
+ return 0;
+
+ cmd_error:
+ return -EIO;
+ fatal_card_error:
+ return -ENODEV;
+}
+
+static int sdio_card_init(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int t;
+ int ret;
+
+ for (t = 0; t < SDD_CARD_INIT_RETRY_MAX; t++) {
+ ret = sdio_card_init_sequence(slot);
+ if (ret == -ENODEV)
+ goto fatal_card_error;
+ if (ret == 0)
+ break;
+ }
+ if (t == SDD_CARD_INIT_RETRY_MAX) {
+ goto fatal_card_error;
+ }
+
+ slotp->io_ops = sdio_io_ops;
+
+ return 0;
+
+ fatal_card_error:
+ /* Card isn't functional, present, or is not supported. */
+ return -ENODEV;
+}
+
+int sdio_card_start(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int r;
+
+ sdio_event_log(slot, SDD_EVENT_POWER_ON);
+
+ slot->card_power(slot, SDIO_POWER_3V3);
+ os_sleep_ms(SDIO_POWER_UP_TIME_MS);
+ slotp->card_powered = 1;
+
+ sdio_event_log(slot, SDD_EVENT_CLOCK_FREQ, SDIO_CLOCK_FREQ_MIN);
+ slot->clock_freq = SDIO_CLOCK_FREQ_MIN;
+ slot->bus_width = 1;
+
+ if (slot->type == SDD_SLOT_TYPE_SPI_CSPI && cspi_is_enabled(slot)) {
+ r = cspi_card_init(slot);
+ } else {
+ r = sdio_card_init(slot);
+ }
+ if (r) {
+ slot_error(slot, "card initialization failed");
+ }
+ return r;
+}
+
+void sdio_card_stop(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ sdio_event_log(slot, SDD_EVENT_POWER_OFF);
+
+ slot_set_bus_freq(slot, SDD_BUS_FREQ_OFF);
+ slot->card_power(slot, SDIO_POWER_OFF);
+ slotp->card_powered = 0;
+}
+
+static int sdio_card_read_info_f0(struct sdio_dev *fdev)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ uint8_t card_caps, high_speed;
+ uint16_t manfid[2];
+ uint8_t funce[CISTPL_FUNCE_00_SIZE];
+ int ret;
+
+ fdev->io->read8(fdev, 0, SDIO_CCCR_CARD_CAPS, &card_caps);
+ if (card_caps & SDIO_CCCR_CARD_CAPS_LSC) {
+ slotp->max_bus_width = (card_caps & SDIO_CCCR_CARD_CAPS_4BLS) ? 4 : 1;
+ } else {
+ slotp->max_bus_width = 4;
+ }
+
+ fdev->io->read8(fdev, 0, SDIO_CCCR_HIGH_SPEED, &high_speed);
+ slotp->supports_high_speed = (high_speed & SDIO_CCCR_HIGH_SPEED) ? 1 : 0;
+
+ /* read common CIS ptr */
+ ret = sdio_cis_read_ptr_reg(fdev, SDIO_CCCR_CIS_PTR, &fdevp->cis_ptr);
+ if (ret) {
+ return ret;
+ }
+ if (fdevp->cis_ptr < 0x1000 || fdevp->cis_ptr > 0x17000) {
+ slot_error(slot, "invalid common CIS ptr (0x%06x)", fdevp->cis_ptr);
+ return -EINVAL;
+ }
+
+ /* read manfid from CIS */
+ ret = sdio_cis_get_tuple(fdev, CISTPL_MANFID, &manfid, CISTPL_MANFID_SIZE);
+ if (ret) {
+ return ret;
+ }
+ fdev->vendor_id = os_le16_to_cpu(manfid[0]);
+ fdev->device_id = os_le16_to_cpu(manfid[1]);
+
+ /* read maximum bus clock frequency from CIS */
+ slotp->max_card_freq = SDIO_CLOCK_FREQ_MIN;
+ if (sdio_cis_get_tuple(fdev, CISTPL_FUNCE, &funce, CISTPL_FUNCE_00_SIZE) == 0) {
+ /* decode TPLFE_MAX_TRAN_SPEED */
+ static const int val[16] = {
+ 0 /* reserved */, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80,
+ };
+ static const int unit_10hz[8] = {
+ 10000, 100000, 1000000, /* rest are reserved */
+ };
+ int max_tran_speed = val[(funce[3] & 0x78) >> 3] * unit_10hz[funce[3] & 0x7];
+ if (max_tran_speed > 0) {
+ if (max_tran_speed > slot->caps.max_bus_freq) {
+ max_tran_speed = slot->caps.max_bus_freq;
+ }
+ if (sdd_max_bus_freq != 0 && max_tran_speed > sdd_max_bus_freq) {
+ max_tran_speed = sdd_max_bus_freq;
+ }
+ slotp->max_card_freq = max_tran_speed;
+ } else {
+ slot_warning(slot, "invalid TPLFE_MAX_TRAN_SPEED (%02x)", funce[3]);
+ }
+ }
+
+ slot_debug(slot, "initialized card %04x:%04x", fdev->vendor_id, fdev->device_id);
+
+ return 0;
+}
+
+static int sdio_card_read_info_fn(struct sdio_dev *fdev)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ int func = fdev->function;
+ uint8_t funce_dat[CISTPL_FUNCE_01_SIZE];
+ int ret;
+
+ /* read func CIS ptr */
+ ret = sdio_cis_read_ptr_reg(fdev, SDIO_FBR_CIS_PTR(func), &fdevp->cis_ptr);
+ if (ret) {
+ return ret;
+ }
+ if (fdevp->cis_ptr < 0x1000 || fdevp->cis_ptr > 0x17000) {
+ slot_error(slot, "invalid function %d CIS ptr (0x%06x)", func, fdevp->cis_ptr);
+ return -EINVAL;
+ }
+
+ /* iface type */
+ ret = fdev->io->read8(fdev, 0, SDIO_FBR_STD_IFACE(func), &fdev->interface);
+ if (ret) {
+ return ret;
+ }
+
+ /* max blocksize from CIS */
+ ret = sdio_cis_get_tuple(fdev, CISTPL_FUNCE, funce_dat, CISTPL_FUNCE_01_SIZE);
+ if (ret) {
+ return ret;
+ }
+ fdev->max_blocksize = (funce_dat[0x0c] & 0xff) | ((funce_dat[0x0d] & 0xff) << 8);
+
+ slot_debug(slot, "F%d: iface: %02x, blk size: %d",
+ func, fdev->interface, fdev->max_blocksize);
+
+ return 0;
+}
+
+static int sdio_card_read_info(struct sdio_dev *fdev)
+{
+ struct sdio_slot *slot = fdev->priv->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ int ret;
+
+ if (fdev->function == 0) {
+ return sdio_card_read_info_f0(fdev);
+ }
+
+ if (fdev->function != SDD_UIF_FUNC) {
+ ret = sdio_card_read_info_fn(fdev);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ fdev->vendor_id = slotp->functions[0]->vendor_id;
+ fdev->device_id = slotp->functions[0]->device_id;
+
+ return 0;
+}
+
+static void sdio_card_configure_f0(struct sdio_dev *fdev)
+{
+ struct sdio_slot *slot = fdev->priv->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ int bus_width = 1;
+
+ /*
+ * Ensure F0 register are in a sensible state:
+ * - disable all functions.
+ * - disable card detect resistor.
+ * - enable continuous SPI interrupt.
+ */
+ fdev->io->write8(fdev, 0, SDIO_CCCR_IO_EN, 0x00);
+ fdev->io->write8(fdev, 0, SDIO_CCCR_BUS_IFACE_CNTL,
+ SDIO_CCCR_BUS_IFACE_CNTL_CD_R_DISABLE
+ | SDIO_CCCR_BUS_IFACE_CNTL_ECSI);
+
+ if (slot->type == SDD_SLOT_TYPE_SD) {
+ /* Configure 4 bit mode if supported by host and card. */
+ if (slot->caps.max_bus_width == 4 && slotp->max_bus_width == 4) {
+ bus_width = 4;
+ }
+ slot_set_bus_width(slot, bus_width);
+ }
+
+ /* Set master and per-function interrupt enables. */
+ fdev->io->write8(fdev, 0, SDIO_CCCR_INT_EN, (1 << (slotp->num_functions + 1)) - 1);
+}
+
+static void sdio_card_configure_func(struct sdio_dev *fdev)
+{
+ if (fdev->function == 0) {
+ sdio_card_configure_f0(fdev);
+ }
+
+ sdio_idle_function(fdev);
+}
+
+static int sdio_card_init_func(struct sdio_slot *slot, int func)
+{
+ struct sdio_dev *fdev;
+ struct sdio_dev_priv *fdevp;
+ int ret = -EIO;
+
+ fdev = sdio_dev_alloc(slot, func);
+ if (!fdev) {
+ return -ENOMEM;
+ }
+ fdevp = fdev->priv;
+
+ ret = sdio_card_read_info(fdev);
+ if (ret) {
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ sdio_dev_free(fdev);
+ return ret;
+}
+
+void sdio_card_configure(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int f;
+
+ /*
+ * Try enabling CSPI mode if the slot supports it.
+ */
+ if (slot->type == SDD_SLOT_TYPE_SPI_CSPI) {
+ cspi_enable(slot);
+ }
+
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ struct sdio_dev *fdev = slotp->functions[f];
+ if (fdev != NULL) {
+ sdio_card_configure_func(fdev);
+ fdev->blocksize = 0;
+ sdio_func_set_block_size(fdev, 0);
+ }
+ }
+}
+
+/**
+ * Notify the SDIO layer that a card has been inserted.
+ *
+ * Callable from: thread context.
+ *
+ * @param slot the slot for the inserted card.
+ *
+ * @ingroup sdriver
+ */
+void sdio_card_inserted(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int f;
+
+ os_mutex_lock(&sdio_core_mutex);
+
+ if (slotp->card_present)
+ goto out;
+
+ slot_info(slot, "card inserted");
+
+ slotp->card_present = 1;
+
+ if (sdio_card_start(slot) < 0) {
+ goto out;
+ }
+ slot_debug(slot, "card has %d functions", slotp->num_functions);
+
+ if (sdio_card_init_func(slot, 0) < 0) {
+ goto out;
+ }
+ for (f = 1; f <= slotp->num_functions; f++) {
+ sdio_card_init_func(slot, f);
+ }
+ sdio_card_init_func(slot, SDD_UIF_FUNC);
+ sdio_card_configure(slot);
+
+ /*
+ * Add successfully initialized functions to the core.
+ */
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ struct sdio_dev *fdev = slotp->functions[f];
+ if (fdev) {
+ sdio_dev_add(fdev);
+ }
+ }
+
+ out:
+ os_mutex_unlock(&sdio_core_mutex);
+}
+
+/**
+ * Notify the SDIO layer that a card has been removed
+ *
+ * Callable from: thread context.
+ *
+ * @param slot the slot for the removed card.
+ *
+ * @ingroup sdriver
+ */
+void sdio_card_removed(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int f;
+
+ os_mutex_lock(&sdio_core_mutex);
+
+ if (!slotp->card_present) {
+ goto out;
+ }
+
+ slot_info(slot, "card removed");
+
+ slotp->card_present = 0;
+
+ for (f = SDD_MAX_FUNCTIONS-1; f >= 0; f--) {
+ struct sdio_dev *fdev = slotp->functions[f];
+ if (fdev) {
+ sdio_dev_del(fdev);
+ }
+ }
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ struct sdio_dev *fdev = slotp->functions[f];
+ sdio_dev_free(fdev);
+ }
+
+ sdio_card_stop(slot);
+
+ out:
+ os_mutex_unlock(&sdio_core_mutex);
+}
+
+/**
+ * Perform a hard reset of the card (if the slot is capable) and
+ * reinitialize the card.
+ *
+ * @param fdev an SDIO device of the card.
+ *
+ * @return 0 if a hard reset was performed and the card successfully
+ * reinitialized.
+ * @return 1 if the slot is not capable of hard resets.
+ * @return -ve if the reinitialization failed.
+ *
+ * @ingroup fdriver
+ */
+int sdio_hard_reset(struct sdio_dev *fdev)
+{
+ struct sdio_slot *slot = fdev->priv->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ int reset;
+
+ if (!slot->hard_reset) {
+ return 1;
+ }
+
+ os_mutex_lock(&slotp->card_mutex);
+
+ reset = slot->hard_reset(slot);
+ if (reset == 0) {
+ slotp->current_clock_freq = 0; /* slot driver may have changed the clock */
+ sdio_event_log(slot, SDD_EVENT_RESET);
+ reset = sdio_card_start(slot);
+ if (reset == 0) {
+ sdio_card_configure(slot);
+ sdio_func_set_max_bus_freq(fdev, fdev->priv->max_freq);
+ }
+ }
+
+ os_mutex_unlock(&slotp->card_mutex);
+
+ return reset;
+}
+
+#if SDD_CARD_IS_REMOVABLE
+
+static void sdio_card_detect_thread_func(void *data)
+{
+ struct sdio_slot *slot = data;
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ slotp->card_present = 0;
+
+ while (!os_thread_should_stop(&slotp->card_detect_thread)) {
+ int card_present = slot->card_present(slot);
+ if (card_present) {
+ sdio_card_inserted(slot);
+ }
+ if (!card_present) {
+ sdio_card_removed(slot);
+ }
+ os_try_suspend_thread(&slotp->card_detect_thread);
+ os_sleep_ms(sdd_card_poll_interval_ms);
+ }
+}
+
+/* Called by the driver init, starts the card manager thread. */
+int sdio_card_detect_init(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ char name[12];
+
+ snprintf(name, sizeof(name), "sdio_cd/%d", slotp->id);
+
+ return os_thread_create(&slotp->card_detect_thread, name,
+ sdio_card_detect_thread_func, slot);
+}
+
+void sdio_card_detect_exit(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ os_thread_stop(&slotp->card_detect_thread, NULL);
+
+ sdio_card_removed(slot);
+}
+
+#else /* !SDD_CARD_IS_REMOVABLE */
+
+int sdio_card_detect_init(struct sdio_slot *slot)
+{
+ sdio_card_inserted(slot);
+ return 0;
+}
+
+void sdio_card_detect_exit(struct sdio_slot *slot)
+{
+ sdio_card_removed(slot);
+}
+
+#endif
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_cis.c b/unifi_hostsw_linux_147/sdioemb/sdio_cis.c
new file mode 100644
index 0000000..232862f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_cis.c
@@ -0,0 +1,101 @@
+/*
+ * SDIO CIS access.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <sdioemb/sdio_cis.h>
+
+#include "sdio_layer.h"
+
+/**
+ * Read a 24 bit CIS pointer register.
+ */
+int sdio_cis_read_ptr_reg(struct sdio_dev *fdev, uint32_t addr, uint32_t *ptr)
+{
+ uint32_t cis_ptr = 0;
+ int b;
+
+ for (b = 0; b < 3; b++) {
+ uint8_t p;
+ int ret = fdev->io->read8(fdev, 0, addr + b, &p);
+ if (ret < 0)
+ return ret;
+ cis_ptr |= p << (b * 8);
+ }
+ *ptr = cis_ptr;
+ return 0;
+}
+
+/**
+ * Read a CIS tuple.
+ *
+ * Copies the specified function's CIS tuple into a buffer. The tuple
+ * ID and link pointer are not copied.
+ *
+ * @param fdev function to read CIS from.
+ * @param tuple ID of tuple to find.
+ * @param buf destination buffer for tuple data.
+ * @param len length of \a buf.
+ *
+ * @returns 0 on success; -ve on error:
+ * -ENXIO - no such tuple found,
+ * -EINVAL - buffer is shorter than the tuple,
+ * -EIO,-ETIMEDOUT - I/O error while reading from card.
+ *
+ * @ingroup fdriver
+ */
+int sdio_cis_get_tuple(struct sdio_dev *fdev, uint8_t tuple,
+ void *buf, size_t len)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ uint8_t *bbuf = buf;
+ uint32_t cis_ptr;
+ uint8_t tpl, lnk;
+
+ /* find tuple */
+ cis_ptr = fdevp->cis_ptr;
+ for(;;) {
+ int ret;
+
+ if (cis_ptr >= 0x17000) {
+ /* Valid CIS should have a CISTPL_END so this shouldn't happen. */
+ return -ENXIO;
+ }
+
+ ret = fdev->io->read8(fdev, 0, cis_ptr++, &tpl);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = fdev->io->read8(fdev, 0, cis_ptr++, &lnk);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (tpl == CISTPL_END) {
+ return -ENXIO;
+ }
+ if (tpl == tuple) {
+ break;
+ }
+ cis_ptr += lnk;
+ }
+
+ if (lnk > len) {
+ return -EINVAL;
+ }
+
+ /* copy tuple data */
+ for (; lnk > 0; lnk--) {
+ int ret;
+
+ ret = fdev->io->read8(fdev, 0, cis_ptr++, bbuf++);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_cmd.c b/unifi_hostsw_linux_147/sdioemb/sdio_cmd.c
new file mode 100644
index 0000000..91a1d24
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_cmd.c
@@ -0,0 +1,180 @@
+/*
+ * Command queuing and dispatch.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "sdio_layer.h"
+
+static int queue_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct sdio_dev *fdev = cmd->owner;
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ os_int_status_t istate;
+ int ret = 0;
+
+ os_spinlock_lock_intsave(&slotp->lock, &istate);
+
+ if (fdevp->queued_cmd == NULL) {
+ fdevp->queued_cmd = cmd;
+ } else {
+ ret = -EAGAIN;
+ }
+
+ os_spinlock_unlock_intrestore(&slotp->lock, &istate);
+
+ return ret;
+}
+
+
+static void dequeue_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct sdio_dev *fdev = cmd->owner;
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ os_int_status_t istate;
+
+ os_spinlock_lock_intsave(&slotp->lock, &istate);
+
+ fdevp->queued_cmd = NULL;
+ slotp->busy = 0;
+
+ os_spinlock_unlock_intrestore(&slotp->lock, &istate);
+}
+
+
+static void check_queues(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_cmd *cmd = NULL;
+ os_int_status_t istate;
+
+ /* round-robin all functions and submit the first command found. */
+ os_spinlock_lock_intsave(&slotp->lock, &istate);
+
+ if (!slotp->busy) {
+ int f;
+ struct sdio_dev *fdev;
+ struct sdio_dev_priv *fdevp;
+
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ slotp->last_function++;
+ if (slotp->last_function >= SDD_MAX_FUNCTIONS) {
+ slotp->last_function = 0;
+ }
+
+ fdev = slotp->functions[slotp->last_function];
+ if (!fdev) {
+ continue;
+ }
+ fdevp = fdev->priv;
+
+ cmd = fdevp->queued_cmd;
+ if (cmd) {
+ slotp->busy = 1;
+ slotp->active |= 1 << fdev->function;
+ break;
+ }
+ }
+ }
+
+ os_spinlock_unlock_intrestore(&slotp->lock, &istate);
+
+ if (cmd) {
+ slot_start_cmd(slot, cmd);
+ }
+}
+
+/**
+ * Submit an SDIO command to a device.
+ *
+ * The command will be queued and executed when the card becomes
+ * available.
+ *
+ * Each SDIO device has a queue with one entry. Therefore, only one
+ * command per SDIO device may be submitted at a time.
+ *
+ * @param fdev the SDIO device submitting the command.
+ * @param cmd the command to submit.
+ *
+ * @return \e 0 if the command was queued.
+ * @return \e -EAGAIN if the command queue is full.
+ * @return \e -EINVAL if the data transfer is invalid (unsupported
+ * buffer alignment or the length is not a valid byte or block mode
+ * transfer).
+ *
+ * @see sdio_dev::io
+ *
+ * @ingroup fdriver
+ */
+int sdio_start_cmd(struct sdio_dev *fdev, struct sdio_cmd *cmd)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ int ret;
+
+ /*
+ * Sanity check data transfers:
+ * - length is a valid block or byte mode transfer).
+ * - some slot drivers can't handle odd-byte aligned buffers.
+ */
+ if (cmd->data) {
+ if ((cmd->len > fdev->blocksize && cmd->len % fdev->blocksize != 0)
+ || cmd->len == 0)
+ {
+ slot_warning(slot, "F%d: invalid length (cmd->len = %d)",
+ fdev->function, cmd->len);
+ return -EINVAL;
+ }
+ if ((unsigned long)cmd->data & 1) {
+ slot_warning(slot, "F%d: unsupported alignment (cmd->data = %p)",
+ fdev->function, cmd->data);
+ return -EINVAL;
+ }
+ }
+
+ cmd->owner = fdev;
+
+ ret = queue_cmd(slot, cmd);
+ if (ret) {
+ return ret;
+ }
+ check_queues(slot);
+ return 0;
+}
+
+
+/**
+ * Notify the SDIO layer that an SDIO commmand has completed.
+ *
+ * Slot drivers should set the \a cmd's status and response and call
+ * this when a command has completed (either successfully or not).
+ *
+ * Callable from: interrupt context.
+ *
+ * @param slot the slot which completed the command.
+ * @param cmd the completed command.
+ *
+ * @ingroup sdriver
+ */
+void sdio_cmd_complete(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ sdio_event_log_set_response(slot, cmd);
+
+ if (cmd->status && !slot->card_present(slot)) {
+ cmd->status = SDD_CMD_ERR_NO_CARD;
+ }
+
+ if (cmd->flags & SDD_CMD_FLAG_RAW) {
+ cmd->callback(cmd);
+ } else {
+ dequeue_cmd(slot, cmd);
+
+ cmd->callback(cmd);
+
+ check_queues(slot);
+ }
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_config.h b/unifi_hostsw_linux_147/sdioemb/sdio_config.h
new file mode 100644
index 0000000..d93683e
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_config.h
@@ -0,0 +1,105 @@
+/*
+ * Compile time configuration defaults.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SDD_CONFIG_H
+#define _SDD_CONFIG_H
+
+/**
+ * @defgroup config Compile-time configuration
+ *
+ * Various compile time options are set with \#define's. These may be
+ * overridden by providing appropriate compiler options (e.g., with
+ * gcc's -D option).
+ *
+ * Defaults are provided in sdio_config.h.
+ *
+ *@{
+ */
+
+/**
+ * @def SDD_SLOTS_MAX
+ *
+ * Maximum number of SDIO slots that may be registered with the core.
+ */
+#ifndef SDD_SLOTS_MAX
+# define SDD_SLOTS_MAX 4
+#endif
+
+/**
+ * @def SDD_FDRIVERS_MAX
+ *
+ * Maxium number of function drivers that may be registered with the
+ * core.
+ */
+#ifndef SDD_FDRIVERS_MAX
+# define SDD_FDRIVERS_MAX 4
+#endif
+
+/**
+ * @def SDD_FDEVS_MAX
+ *
+ * Maximum number of functions supported by the core.
+ */
+#ifndef SDD_FDEVS_MAX
+# define SDD_FDEVS_MAX 8
+#endif
+
+/**
+ * @def SDD_CARD_INIT_RETRY_MAX
+ *
+ * Maximum number of times to try to initialize a card.
+ */
+#ifndef SDD_CARD_INIT_RETRY_MAX
+# define SDD_CARD_INIT_RETRY_MAX 3
+#endif
+
+/**
+ * @def SDD_CARD_READY_TIMEOUT_MS
+ *
+ * Time (in ms) to wait for the card to become ready during the
+ * initialization sequence.
+ */
+#ifndef SDD_CARD_READY_TIMEOUT_MS
+# define SDD_CARD_READY_TIMEOUT_MS 100
+#endif
+
+/**
+ * @def SDD_CARD_IS_REMOVABLE
+ *
+ * Non-zero if the card is removable, zero if the card is always
+ * inserted (e.g., it's wired directly to the SD host controller).
+ *
+ * A thread is used when detecting removable cards.
+ */
+#ifndef SDD_CARD_IS_REMOVABLE
+# define SDD_CARD_IS_REMOVABLE 1
+#endif
+
+/**
+ * @def SDD_CSPI_REG_PADDING
+ *
+ * Amount of CSPI register padding in octets. The default of 0 should
+ * be fine for all chips and bus speeds less than 25 MHz.
+ */
+#ifndef SDD_CSPI_REG_PADDING
+# define SDD_CSPI_REG_PADDING 0
+#endif
+
+/**
+ * @def SDD_CSPI_BURST_PADDING
+ *
+ * Amount of CSPI burst padding in octets. The default of 2 should be
+ * fine for all chips and bus speeds less than 25 MHz.
+ */
+#ifndef SDD_CSPI_BURST_PADDING
+# define SDD_CSPI_BURST_PADDING 2
+#endif
+
+/*@}*/
+
+#endif /* _SDD_CONFIG_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_core.c b/unifi_hostsw_linux_147/sdioemb/sdio_core.c
new file mode 100644
index 0000000..dd29eb9
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_core.c
@@ -0,0 +1,278 @@
+/*
+ * SDIO device management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "sdio_config.h"
+#include "sdio_layer.h"
+#include "sdio_version.h"
+
+/**
+ * Mutex protecting card inserts/removes and driver registration.
+ */
+os_mutex_t sdio_core_mutex;
+
+static struct sdio_func_driver *registered_fdrivers[SDD_FDRIVERS_MAX];
+
+static struct sdio_dev *available_funcs[SDD_FDEVS_MAX];
+
+/**
+ * Initialize the SDIO stack.
+ *
+ * This must be called from the OS specific entry point of the sdio
+ * module.
+ */
+void sdio_core_init(void)
+{
+ slot_info(NULL, "CSR SDIO driver (sdioemb) v%d%s %s",
+ SDD_BUILDID, SDD_BUILDID_EXTRA, SDD_BUILD_DATE);
+
+ os_mutex_init(&sdio_core_mutex);
+}
+
+static int sdio_driver_probe(struct sdio_func_driver *fdriver, struct sdio_dev *fdev)
+{
+ struct sdio_id_table *id;
+ int ret;
+
+ for (id = fdriver->id_table; id->vendor_id != 0; id++) {
+ if ((id->vendor_id == SDD_ANY_ID || id->vendor_id == fdev->vendor_id) &&
+ (id->device_id == SDD_ANY_ID || id->device_id == fdev->device_id) &&
+ ((id->function == SDD_ANY_FUNC && fdev->function != SDD_UIF_FUNC)
+ || id->function == fdev->function) &&
+ (id->interface == SDD_ANY_IFACE || id->interface == fdev->interface))
+ {
+ sdio_power_on(fdev);
+ sdio_set_block_size(fdev, 0);
+ sdio_set_max_bus_freq(fdev, SDD_BUS_FREQ_DEFAULT);
+
+ fdev->driver = fdriver;
+ ret = fdriver->probe(fdev);
+ if (ret != 0) {
+ sdio_power_off(fdev);
+ fdev->driver = NULL;
+ }
+ return ret;
+ }
+ }
+ return -ENODEV;
+}
+
+static void sdio_driver_remove(struct sdio_func_driver *fdriver, struct sdio_dev *fdev)
+{
+ fdriver->remove(fdev);
+ fdev->driver = NULL;
+ sdio_idle_function(fdev);
+ sdio_power_off(fdev);
+}
+
+/**
+ * Register a function driver with the core.
+ *
+ * If any inserted cards that have functions that match \a fdriver's
+ * list of supported functions then \a fdriver's probe() function will
+ * be called for those functions.
+ *
+ * @param fdriver the function driver to register.
+ *
+ * @returns 0 on success; -ve on error:
+ * -ENOMEM - maximum number of function drivers are already registered.
+ *
+ * @ingroup fdriver
+ */
+int sdio_driver_register(struct sdio_func_driver *fdriver)
+{
+ int i;
+
+ os_mutex_lock(&sdio_core_mutex);
+
+ for (i = 0; i < SDD_FDRIVERS_MAX; i++) {
+ if (registered_fdrivers[i] == NULL) {
+ registered_fdrivers[i] = fdriver;
+ break;
+ }
+ }
+ if (i == SDD_FDRIVERS_MAX) {
+ os_mutex_unlock(&sdio_core_mutex);
+ return -ENOMEM;
+ }
+
+ slot_debug(NULL, "registered %s driver", fdriver->name);
+
+ for (i = 0; i < SDD_FDEVS_MAX; i++) {
+ if (available_funcs[i] && available_funcs[i]->driver == NULL) {
+ sdio_driver_probe(fdriver, available_funcs[i]);
+ }
+ }
+
+ os_mutex_unlock(&sdio_core_mutex);
+
+ return 0;
+}
+
+/**
+ * Unregister a function driver from the core.
+ *
+ * \a fdriver's remove() will be called for any SDIO devices currently
+ * attached to the driver.
+ *
+ * @param fdriver the function driver to unregister.
+ *
+ * @ingroup fdriver
+ */
+void sdio_driver_unregister(struct sdio_func_driver *fdriver)
+{
+ int i;
+
+ slot_debug(NULL, "unregister %s driver", fdriver->name);
+
+ os_mutex_lock(&sdio_core_mutex);
+
+ /* Remove any functions attached to the driver. */
+ for (i = 0; i < SDD_FDEVS_MAX; i++) {
+ struct sdio_dev *fdev = available_funcs[i];
+ if (fdev && fdev->driver == fdriver) {
+ sdio_driver_remove(fdriver, fdev);
+ }
+ }
+
+ /* Remove fdriver from the registered driver list. */
+ for (i = 0; i < SDD_FDRIVERS_MAX; i++) {
+ if (registered_fdrivers[i] == fdriver) {
+ registered_fdrivers[i] = NULL;
+ }
+ }
+
+ os_mutex_unlock(&sdio_core_mutex);
+}
+
+struct sdio_dev *sdio_dev_alloc(struct sdio_slot *slot, int func)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_dev *fdev;
+ struct sdio_dev_priv *fdevp;
+
+ fdev = os_alloc(sizeof(struct sdio_dev) + sizeof(struct sdio_dev_priv));
+ if (!fdev) {
+ return NULL;
+ }
+ slotp->functions[func] = fdev;
+
+ fdev->priv = (struct sdio_dev_priv *)&fdev[1];
+ fdev->function = func;
+ fdev->slot_id = slotp->id;
+ fdev->io = &slotp->io_ops;
+
+ fdevp = fdev->priv;
+ fdevp->slot = slot;
+
+ return fdev;
+}
+
+void sdio_dev_free(struct sdio_dev *fdev)
+{
+ struct sdio_slot_priv *slotp;
+
+ if (fdev == NULL)
+ return;
+
+ slotp = fdev->priv->slot->priv;
+
+ slotp->functions[fdev->function] = NULL;
+ os_free(fdev);
+}
+
+int sdio_dev_add(struct sdio_dev *fdev)
+{
+ int err;
+ int i;
+
+ err = sdio_os_dev_add(fdev);
+ if (err < 0) {
+ return err;
+ }
+
+ for (i = 0; i < SDD_FDEVS_MAX; i++) {
+ if (available_funcs[i] == NULL) {
+ available_funcs[i] = fdev;
+ break;
+ }
+ }
+ if (i == SDD_FDEVS_MAX)
+ return -ENOMEM;
+
+ for (i = 0; i < SDD_FDRIVERS_MAX; i++) {
+ if (registered_fdrivers[i]) {
+ sdio_driver_probe(registered_fdrivers[i], fdev);
+ }
+ }
+ return 0;
+}
+
+void sdio_dev_del(struct sdio_dev *fdev)
+{
+ int i;
+
+ if (fdev->driver) {
+ sdio_driver_remove(fdev->driver, fdev);
+ }
+
+ for (i = 0; i < SDD_FDEVS_MAX; i++) {
+ if (available_funcs[i] == fdev) {
+ available_funcs[i] = NULL;
+ break;
+ }
+ }
+
+ sdio_os_dev_del(fdev);
+}
+
+static void slot_message(enum os_print_level level, struct sdio_slot *slot,
+ const char *fmt, va_list args)
+{
+ const char *name = NULL;
+
+ if (slot) {
+ name = slot->name ? slot->name : "(unnamed slot)";
+ }
+ os_vprint(level, "sdio: ", name, fmt, args);
+}
+
+void slot_error(struct sdio_slot *slot, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ slot_message(OS_PRINT_ERROR, slot, fmt, args);
+ va_end(args);
+}
+
+void slot_warning(struct sdio_slot *slot, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ slot_message(OS_PRINT_WARNING, slot, fmt, args);
+ va_end(args);
+}
+
+void slot_info(struct sdio_slot *slot, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ slot_message(OS_PRINT_INFO, slot, fmt, args);
+ va_end(args);
+}
+
+void slot_debug(struct sdio_slot *slot, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ slot_message(OS_PRINT_DEBUG, slot, fmt, args);
+ va_end(args);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_cspi.c b/unifi_hostsw_linux_147/sdioemb/sdio_cspi.c
new file mode 100644
index 0000000..c6c76eb
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_cspi.c
@@ -0,0 +1,225 @@
+/*
+ * CSPI mode control.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <sdioemb/cspi.h>
+#include <sdioemb/sdio_csr.h>
+
+#include "sdio_layer.h"
+#include "sdio_config.h"
+
+/**
+ * Map of card manufacture and card IDs to the generic function and
+ * address of the SDIO_MODE register.
+ *
+ * New chips that support CSPI should be added to this table.
+ */
+static const struct sdio_mode_map {
+ uint16_t manf_id;
+ uint16_t card_id;
+ int gen_func;
+ uint32_t addr;
+} sdio_mode[] = {
+ {
+ SDIO_MANF_ID_CSR,
+ SDIO_CARD_ID_CSR_BC6,
+ 2,
+ 0xfc26 << 1,
+ },
+ {
+ SDIO_MANF_ID_CSR,
+ SDIO_CARD_ID_CSR_BC7,
+ 2,
+ 0xf935 << 1,
+ },
+ {
+ SDIO_MANF_ID_CSR,
+ SDIO_CARD_ID_CSR_DASH,
+ 2,
+ 0xf935 << 1,
+ },
+ {
+ SDIO_MANF_ID_CSR,
+ SDIO_CARD_ID_CSR_CINDERELLA,
+ 1,
+ 0xf935 << 1,
+ },
+};
+
+#define NUM_CSPI_CARDS (sizeof(sdio_mode)/sizeof(sdio_mode[0]))
+
+static struct sdio_card_io_ops cspi_io_ops = {
+ cspi_io_read8,
+ cspi_io_write8,
+ cspi_io_read,
+ cspi_io_write,
+};
+
+/**
+ * Determine if CSPI is enabled on a card.
+ *
+ * A CSPI write to the CSPI_PADDING register with default values is
+ * attempted. (Can't do a read as the padding values are not known.)
+ *
+ * @param slot the slot for the card.
+ *
+ * @return true if CSPI is enabled; false otherwise.
+ */
+int cspi_is_enabled(struct sdio_slot *slot)
+{
+ uint16_t cspi_padding;
+
+ slot->cspi_reg_pad = CSPI_PADDING_REG_DFLT;
+ slot->cspi_burst_pad = CSPI_PADDING_BURST_DFLT;
+
+ cspi_padding = CSPI_PADDING_REG(slot->cspi_reg_pad)
+ | CSPI_PADDING_BURST(slot->cspi_burst_pad);
+
+ return cspi_raw_word_cmd(slot, CSPI_WRITE | CSPI_FUNC(0), CSPI_PADDING, &cspi_padding) == 0;
+}
+
+/**
+ * Count the number of functions when in CSPI mode.
+ *
+ * The number of functions is determined by the settable bits in the
+ * CCCR Interrupt Enable register.
+ *
+ * @param slot the slot for the card.
+ *
+ * @return number of functions in the card; -ve on I/O error.
+ */
+static int cspi_num_functions(struct sdio_slot *slot)
+{
+ int r, n = 0;
+ uint16_t int_en = 0xfe; /* leave MIE clear */
+
+ r = cspi_raw_word_cmd(slot, CSPI_WRITE | CSPI_FUNC(0), SDIO_CCCR_INT_EN, &int_en);
+ if (r) {
+ return r;
+ }
+ r = cspi_raw_word_cmd(slot, CSPI_READ | CSPI_FUNC(0), SDIO_CCCR_INT_EN, &int_en);
+ if (r) {
+ return r;
+ }
+
+ while (int_en >>= 1) {
+ n++;
+ }
+ return n;
+}
+
+/**
+ * Initialize a card using the CSPI transport.
+ *
+ * @param slot the slot for the card.
+ *
+ * @return 0 on success; -ve on I/O error.
+ *
+ * @see sdio_card_init
+ */
+int cspi_card_init(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int n;
+
+ n = cspi_num_functions(slot);
+ if (n < 0) {
+ return n;
+ }
+ slotp->num_functions = n;
+
+ slotp->io_ops = cspi_io_ops;
+
+ return 0;
+}
+
+/**
+ * Enable and configure CPSI mode by writing the SDIO_MODE,
+ * CSPI_PADDING and CSPI_MODE registers.
+ *
+ * @param sdev the SDIO device for the generic function.
+ * @param addr byte address of the SDIO_MODE register.
+ * @param val value to write to SDIO_MODE.
+ *
+ * @return 0 on success.
+ * @return -EIO, -ETIMEDOUT if I/O error occured while writing to card.
+ */
+static int switch_to_cspi(struct sdio_dev *sdev, uint32_t addr, uint8_t val)
+{
+ struct sdio_dev_priv *sdevp = sdev->priv;
+ struct sdio_slot *slot = sdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ int ret;
+
+ slot->cspi_reg_pad = SDD_CSPI_REG_PADDING;
+ slot->cspi_burst_pad = SDD_CSPI_BURST_PADDING;
+
+ /* Ignore errors as the mode switch may occur before the SDIO-SPI
+ * response is generated. */
+ sdio_io_write8(sdev, sdev->function, addr, val);
+
+ ret = cspi_io_write8(sdev, 0, CSPI_PADDING,
+ CSPI_PADDING_REG(slot->cspi_reg_pad)
+ | CSPI_PADDING_BURST(slot->cspi_burst_pad));
+ if (ret) {
+ return ret;
+ }
+ ret = cspi_io_write8(sdev, 0, CSPI_MODE, slot->caps.cspi_mode);
+ if (ret) {
+ return ret;
+ }
+
+ slotp->io_ops = cspi_io_ops;
+
+ return 0;
+}
+
+/**
+ * Enable CSPI mode.
+ *
+ * If the mode switch is successful, the slot's I/O operations will be
+ * set to CSPI operations.
+ *
+ * In the unlikely event of the mode switch being unsuccessful, the
+ * mode of the card (CSPI or still SDIO-SPI) is \e undefined. The
+ * mode switch may be retried by calling cspi_enable() again.
+ *
+ * @param slot the slot to enable CSPI on.
+ *
+ * @return 0 on success.
+ * @return -EINVAL if CSPI mode is not supported by the card.
+ * @return -IO, -ETIMEDOUT if an I/O error occured.
+ */
+int cspi_enable(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_dev *f0 = slotp->functions[0];
+ struct sdio_dev *fdev = NULL;
+ uint32_t addr = 0;
+ int i, ret;
+
+ /* Find generic function and SDIO_MODE address. */
+ for (i = 0; i < NUM_CSPI_CARDS; i++) {
+ if (sdio_mode[i].manf_id == f0->vendor_id
+ && sdio_mode[i].card_id == f0->device_id)
+ {
+ fdev = slotp->functions[sdio_mode[i].gen_func];
+ addr = sdio_mode[i].addr;
+ break;
+ }
+ }
+ if (fdev == NULL) {
+ return -EINVAL;
+ }
+
+ ret = sdio_enable_function(fdev);
+ if (ret) {
+ return ret;
+ }
+
+ return switch_to_cspi(fdev, addr, SDIO_MODE_CSPI_EN);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_event_log.c b/unifi_hostsw_linux_147/sdioemb/sdio_event_log.c
new file mode 100644
index 0000000..cd6e3f4
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_event_log.c
@@ -0,0 +1,292 @@
+/*
+ * Manage a log of SDIO events (commands and interrupts etc.).
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdarg.h>
+
+#include <sdioemb/cspi.h>
+#include "sdio_layer.h"
+
+#ifdef SDD_DEBUG_EVENT_LOG
+
+#if SDD_DEBUG_DATA_BUFFER_LEN > 0
+
+static void init_data_list(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ slotp->event_log.data_buffer = os_alloc_big(SDD_DEBUG_DATA_BUFFER_LEN);
+ if (slotp->event_log.data_buffer == NULL) {
+ slot_warning(slot, "event log data buffer unavailable");
+ }
+
+ slotp->event_log.data_total = slotp->event_log.data_start = 0;
+ slotp->event_log.data_head = slotp->event_log.data_tail = NULL;
+}
+
+static void deinit_data_list(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ os_free_big(slotp->event_log.data_buffer);
+}
+
+uint8_t sdio_event_log_get_data(struct sdio_event_entry *e, unsigned i)
+{
+ unsigned off;
+
+ if (i >= e->cmd.data.length) {
+ return 0;
+ }
+ off = (e->cmd.data.start + i) % SDD_DEBUG_DATA_BUFFER_LEN;
+ return e->cmd.data.buffer[off];
+}
+
+/*
+ * Remove the data element from the head of the data list. i.e.,
+ * remove the oldest data entry.
+ */
+static void shrink_data_list(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ slotp->event_log.data_total -= slotp->event_log.data_head->cmd.data.length;
+ slotp->event_log.data_head->cmd.data.length = 0;
+ slotp->event_log.data_head = slotp->event_log.data_head->cmd.data.next;
+}
+
+static void add_data(struct sdio_slot *slot, struct sdio_event_entry *entry,
+ const uint8_t *data, unsigned length)
+{
+ unsigned l1, l2;
+ struct sdio_slot_priv *slotp = slot->priv;
+ unsigned start = slotp->event_log.data_start;
+
+ if (slotp->event_log.data_buffer == NULL) {
+ return;
+ }
+
+ if (length > SDD_DEBUG_DATA_BUFFER_LEN) {
+ data += length - SDD_DEBUG_DATA_BUFFER_LEN;
+ length = SDD_DEBUG_DATA_BUFFER_LEN;
+ }
+
+ l1 = min(length, SDD_DEBUG_DATA_BUFFER_LEN - start);
+ l2 = length - l1;
+
+ memcpy(slotp->event_log.data_buffer + start, data, l1);
+ if (l2 != 0)
+ memcpy(slotp->event_log.data_buffer, data + l1, l2);
+
+ entry->cmd.data.buffer = slotp->event_log.data_buffer;
+ entry->cmd.data.start = start;
+ entry->cmd.data.length = length;
+ entry->cmd.data.next = NULL;
+
+ if (slotp->event_log.data_head == NULL) {
+ slotp->event_log.data_head = entry;
+ } else {
+ slotp->event_log.data_tail->cmd.data.next = entry;
+ }
+ slotp->event_log.data_tail = entry;
+
+ slotp->event_log.data_total += length;
+ slotp->event_log.data_start =
+ (start + length) % SDD_DEBUG_DATA_BUFFER_LEN;
+
+ while (slotp->event_log.data_total > SDD_DEBUG_DATA_BUFFER_LEN) {
+ shrink_data_list(slot);
+ }
+}
+
+#else /* SDD_DEBUG_DATA_BUFFER_LEN == 0 */
+# define init_data_list(s)
+# define deinit_data_list(s)
+# define shrink_data_list(s)
+# define add_data(s, e, d, l)
+#endif
+
+void sdio_event_log_init(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ os_spinlock_init(&slotp->event_log.lock);
+
+ slotp->event_log.entries = os_alloc_big(sizeof(struct sdio_event_entry)
+ * SDD_DEBUG_EVENT_LOG_LEN);
+ if (slotp->event_log.entries == NULL) {
+ slot_warning(slot, "event log unavailable");
+ return;
+ }
+
+ slotp->event_log.head = slotp->event_log.tail = 0;
+ slotp->event_log.seq_num = 0;
+
+ init_data_list(slot);
+ sdio_os_event_log_init(slot);
+}
+
+void sdio_event_log_deinit(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ sdio_os_event_log_deinit(slot);
+ deinit_data_list(slot);
+
+ os_free_big(slotp->event_log.entries);
+ os_spinlock_destroy(&slotp->event_log.lock);
+}
+
+static void add_event(struct sdio_slot *slot, enum sdio_event_type type)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_event_entry *e;
+
+ e = slotp->event_log.entries + slotp->event_log.head;
+
+ e->time_ms = os_current_time_ms();
+ e->seq_num = slotp->event_log.seq_num++;
+ e->type = type;
+
+ slotp->event_log.head = (slotp->event_log.head + 1) % SDD_DEBUG_EVENT_LOG_LEN;
+ if (slotp->event_log.head == slotp->event_log.tail) {
+ slotp->event_log.tail = (slotp->event_log.tail + 1) % SDD_DEBUG_EVENT_LOG_LEN;
+ }
+}
+
+void sdio_event_log(struct sdio_slot *slot, enum sdio_event_type type, ...)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ va_list args;
+ os_int_status_t istate;
+ const struct sdio_cmd *cmd;
+ struct sdio_event_entry *e;
+
+ va_start(args, type);
+
+ if (slotp->event_log.entries == NULL) {
+ return;
+ }
+
+ os_spinlock_lock_intsave(&slotp->event_log.lock, &istate);
+
+ e = slotp->event_log.entries + slotp->event_log.head;
+
+#if SDD_DEBUG_DATA_BUFFER_LEN > 0
+ /* If we're about to overwrite an log entry for an event that has
+ * data, remove the data for the entry from the data list. */
+ if (slotp->event_log.data_head == e) {
+ shrink_data_list(slot);
+ }
+#endif
+
+ switch (type) {
+ case SDD_EVENT_CMD:
+ cmd = va_arg(args, const struct sdio_cmd *);
+ e->cmd.flags = cmd->flags;
+ if (cmd->flags & SDD_CMD_FLAG_CSPI) {
+ e->cmd.cspi.cmd = cmd->cspi.cmd;
+ e->cmd.cspi.addr = cmd->cspi.addr;
+ if (cmd->cspi.cmd & CSPI_BURST) {
+ e->cmd.cspi.val = cmd->len;
+ } else {
+ e->cmd.cspi.val = cmd->cspi.val;
+ }
+ } else {
+ e->cmd.sdio.cmd = cmd->sdio.cmd;
+ e->cmd.sdio.arg = cmd->sdio.arg;
+ }
+ e->cmd.status = 0xff;
+#if SDD_DEBUG_DATA_BUFFER_LEN > 0
+ e->cmd.data.length = 0;
+#endif
+ break;
+ case SDD_EVENT_CARD_INT:
+ break;
+ case SDD_EVENT_INT_UNMASKED:
+ case SDD_EVENT_INT_MASKED:
+ e->functions = va_arg(args, unsigned);
+ break;
+ case SDD_EVENT_POWER_ON:
+ case SDD_EVENT_POWER_OFF:
+ case SDD_EVENT_RESET:
+ break;
+ case SDD_EVENT_CLOCK_FREQ:
+ e->val = va_arg(args, int);
+ break;
+ }
+ add_event(slot, type);
+
+ os_spinlock_unlock_intrestore(&slotp->event_log.lock, &istate);
+
+ va_end(args);
+}
+
+void sdio_event_log_set_response(struct sdio_slot *slot, const struct sdio_cmd *cmd)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ os_int_status_t istate;
+ unsigned evt;
+ struct sdio_event_entry *e;
+
+ if (slotp->event_log.entries == NULL) {
+ return;
+ }
+
+ os_spinlock_lock_intsave(&slotp->event_log.lock, &istate);
+
+ /* Find latest cmd event without a response. */
+ evt = slotp->event_log.head;
+ do {
+ evt = (evt + (SDD_DEBUG_EVENT_LOG_LEN - 1)) % SDD_DEBUG_EVENT_LOG_LEN;
+ } while (slotp->event_log.entries[evt].type != SDD_EVENT_CMD);
+
+ e = slotp->event_log.entries + evt;
+
+ e->cmd.status = cmd->status;
+ if (cmd->flags & SDD_CMD_FLAG_CSPI) {
+ if (!(cmd->cspi.cmd & CSPI_BURST)) {
+ e->cmd.cspi.val = cmd->cspi.val;
+ }
+ e->cmd.cspi.response = cmd->cspi.response;
+ } else {
+ e->cmd.sdio.response = cmd->sdio.response;
+ }
+
+ if (cmd->data) {
+ add_data(slot, e, cmd->data, cmd->len);
+ }
+
+ os_spinlock_unlock_intrestore(&slotp->event_log.lock, &istate);
+}
+
+static unsigned event_log_len(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ return ((slotp->event_log.head - slotp->event_log.tail) + SDD_DEBUG_EVENT_LOG_LEN)
+ % SDD_DEBUG_EVENT_LOG_LEN;
+}
+
+struct sdio_event_entry *sdio_event_log_get_entry(struct sdio_slot *slot, unsigned n)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ os_int_status_t istate;
+ struct sdio_event_entry *e = NULL;
+
+ os_spinlock_lock_intsave(&slotp->event_log.lock, &istate);
+
+ if (n < event_log_len(slot)) {
+ e = slotp->event_log.entries + (slotp->event_log.tail + n) % SDD_DEBUG_EVENT_LOG_LEN;
+ }
+
+ os_spinlock_unlock_intrestore(&slotp->event_log.lock, &istate);
+
+ return e;
+}
+
+#endif /* #ifdef SDD_DEBUG_EVENT_LOG */
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_event_log.h b/unifi_hostsw_linux_147/sdioemb/sdio_event_log.h
new file mode 100644
index 0000000..b64bd3f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_event_log.h
@@ -0,0 +1,115 @@
+/*
+ * Manage a log of the most recent SDIO events (commands and
+ * interrupts etc.).
+ *
+ * Enable the log by #define'ing SDD_DEBUG_EVENT_LOG_LEN to the
+ * maximum number of events to keep in the log.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+
+#ifndef _SDIO_EVENT_LOG_H
+#define _SDIO_EVENT_LOG_H
+
+#ifdef __linux
+# define SDD_DEBUG_HAVE_EVENT_LOG
+#endif
+
+#ifndef SDD_DEBUG_EVENT_LOG_LEN
+# define SDD_DEBUG_EVENT_LOG_LEN 0
+#endif
+
+#ifndef SDD_DEBUG_DATA_BUFFER_LEN
+# define SDD_DEBUG_DATA_BUFFER_LEN 0
+#endif
+
+#if SDD_DEBUG_EVENT_LOG_LEN > 0 && defined(SDD_DEBUG_HAVE_EVENT_LOG)
+
+#define SDD_DEBUG_EVENT_LOG
+
+enum sdio_event_type {
+ SDD_EVENT_CMD, SDD_EVENT_CARD_INT,
+ SDD_EVENT_INT_UNMASKED, SDD_EVENT_INT_MASKED,
+ SDD_EVENT_POWER_ON, SDD_EVENT_POWER_OFF, SDD_EVENT_RESET,
+ SDD_EVENT_CLOCK_FREQ,
+};
+
+struct sdio_event_entry {
+ unsigned seq_num;
+ unsigned long time_ms;
+ enum sdio_event_type type;
+ union {
+ struct {
+ unsigned flags;
+ union {
+ struct sdio_cmd_resp sdio;
+ struct cspi_cmd_resp cspi;
+ };
+ int status;
+#if SDD_DEBUG_DATA_BUFFER_LEN > 0
+ struct {
+ unsigned length;
+ unsigned start;
+ uint8_t *buffer;
+ struct sdio_event_entry *next;
+ } data;
+#endif
+ } cmd;
+ unsigned functions; /*< bit mask of relevant functions */
+ int val;
+ };
+};
+
+/* A ring buffer of SDIO events. */
+struct sdio_event_log {
+ struct sdio_event_entry *entries;
+ unsigned head;
+ unsigned tail;
+ unsigned seq_num;
+ os_spinlock_t lock;
+
+#if SDD_DEBUG_DATA_BUFFER_LEN > 0
+ /*
+ * So that we don't display old data but can limit ourselves to
+ * the last n octets of interesting data I play some clever tricks
+ * here. I store the sdio_cmd_event's that refer to data in a
+ * linked list and also store the length of data blocks in this
+ * list. When I add a new block to the tail of this list that
+ * increases the data size past the size of sdio_data_buffer I
+ * chop things off the head of the list until the size is OK
+ * again.
+ */
+ uint8_t *data_buffer;
+ unsigned data_start;
+ unsigned data_total;
+ struct sdio_event_entry *data_head;
+ struct sdio_event_entry *data_tail;
+#endif
+};
+
+void sdio_event_log_init(struct sdio_slot *slot);
+void sdio_event_log_deinit(struct sdio_slot *slot);
+void sdio_event_log(struct sdio_slot *slot, enum sdio_event_type type, ...);
+void sdio_event_log_set_response(struct sdio_slot *slot, const struct sdio_cmd *cmd);
+
+struct sdio_event_entry *sdio_event_log_get_entry(struct sdio_slot *slot, unsigned n);
+uint8_t sdio_event_log_get_data(struct sdio_event_entry *e, unsigned i);
+
+void sdio_os_event_log_init(struct sdio_slot *slot);
+void sdio_os_event_log_deinit(struct sdio_slot *slot);
+
+#else
+
+#undef SDD_DEBUG_EVENT_LOG
+
+#define sdio_event_log_init(s)
+#define sdio_event_log_deinit(s)
+#define sdio_event_log(s, t, ...)
+#define sdio_event_log_set_response(s, c)
+
+#endif
+
+#endif /* #ifndef _SDIO_EVENT_LOG_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_func.c b/unifi_hostsw_linux_147/sdioemb/sdio_func.c
new file mode 100644
index 0000000..496d562
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_func.c
@@ -0,0 +1,308 @@
+/*
+ * SDIO function control.
+ *
+ * Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "sdio_layer.h"
+
+/* FIXME: use timeout value in CIS (on 1.1 cards)? */
+#define IO_EN_TIMEOUT_MS 500
+
+/**
+ * Enable the function.
+ *
+ * The function's I/O Enable bit is set and I/O Ready is polled until
+ * it is set.
+ *
+ * Callable from: thread context.
+ *
+ * @param fdev the SDIO device to enable.
+ *
+ * @return 0 on success; -ve on error:
+ * -ETIMEDOUT - time out waiting for I/O Ready to be set,
+ * -EIO or -ETIMEDOUT - a register access failed.
+ *
+ * @ingroup fdriver
+ */
+int sdio_enable_function(struct sdio_dev *fdev)
+{
+ struct sdio_slot_priv *slotp = fdev->priv->slot->priv;
+ uint8_t io_en, io_rdy;
+ int timeout = IO_EN_TIMEOUT_MS;
+ int ret;
+
+ os_mutex_lock(&slotp->card_mutex);
+
+ ret = fdev->io->read8(fdev, 0, SDIO_CCCR_IO_EN, &io_en);
+ if (ret) {
+ goto out_unlock;
+ }
+ io_en |= 1 << fdev->function;
+ ret = fdev->io->write8(fdev, 0, SDIO_CCCR_IO_EN, io_en);
+ if (ret) {
+ goto out_unlock;
+ }
+
+ /* No need to hold the lock while waiting for I/O Ready. */
+ os_mutex_unlock(&slotp->card_mutex);
+
+ while (timeout) {
+ ret = fdev->io->read8(fdev, 0, SDIO_CCCR_IO_READY, &io_rdy);
+ if (ret) {
+ return ret;
+ }
+ if (io_rdy & (1 << fdev->function)) {
+ return 0;
+ }
+
+ os_sleep_ms(1);
+ timeout--;
+ }
+ return -ETIMEDOUT;
+
+ out_unlock:
+ os_mutex_unlock(&slotp->card_mutex);
+ return ret;
+}
+
+/**
+ * Disable the function.
+ *
+ * The function's I/O Enable bit is cleared.
+ *
+ * Callable from: thread context.
+ *
+ * @param fdev the SDIO device to disable.
+ *
+ * @return 0 on success; -ve on error:
+ * -EIO or -ETIMEDOUT - a register access failed.
+ *
+ * @bug To permit a disable/enable sequence to be used as a
+ * per-function reset, disabling a function should wait for I/O Ready
+ * to be cleared.
+ *
+ * @ingroup fdriver
+ */
+int sdio_disable_function(struct sdio_dev *fdev)
+{
+ struct sdio_slot_priv *slotp = fdev->priv->slot->priv;
+ uint8_t io_en;
+ int ret;
+
+ os_mutex_lock(&slotp->card_mutex);
+
+ ret = fdev->io->read8(fdev, 0, SDIO_CCCR_IO_EN, &io_en);
+ if (ret) {
+ goto out;
+ }
+ io_en &= ~(1 << fdev->function);
+ ret = fdev->io->write8(fdev, 0, SDIO_CCCR_IO_EN, io_en);
+
+ out:
+ os_mutex_unlock(&slotp->card_mutex);
+ return ret;
+}
+
+/**
+ * Set a function's block size without taking the card mutex.
+ *
+ * @see sdio_set_block_size()
+ */
+int sdio_func_set_block_size(struct sdio_dev *fdev, int blksz)
+{
+ int ret;
+
+ if (blksz == 0) {
+ blksz = fdev->max_blocksize < 512 ? fdev->max_blocksize : 512;
+ if (sdd_max_block_size && blksz > sdd_max_block_size) {
+ blksz = sdd_max_block_size;
+ }
+ }
+
+ if (fdev->function != SDD_UIF_FUNC && blksz != fdev->blocksize) {
+ /* Ignore -EINVAL (OUT_OF_RANGE in R5) on the first byte as
+ the block size may be invalid until both bytes are written. */
+ ret = fdev->io->write8(fdev, 0, SDIO_FBR_BLK_SIZE(fdev->function),blksz & 0xff);
+ if (ret && ret != -EINVAL) {
+ return ret;
+ }
+ ret = fdev->io->write8(fdev, 0, SDIO_FBR_BLK_SIZE(fdev->function)+1, (blksz >> 8) & 0xff);
+ if (ret) {
+ return ret;
+ }
+ }
+ fdev->blocksize = blksz;
+
+ return 0;
+}
+
+/**
+ * Set a function's block size.
+ *
+ * The default block size is the largest supported by both the
+ * function and the host, with a maximum of 512 to ensure that
+ * arbitrarily sized data transfers use the optimal (least) number of
+ * commands.
+ *
+ * A driver may call this to override the default block size set by
+ * the core. This can be used to set a block size greater than the
+ * maximum that reported by the card; it is the driver's
+ * responsibility to ensure it uses a value that the card supports.
+ *
+ * Callable from: thread context.
+ *
+ * @param fdev the SDIO device.
+ * @param blksz new block size or 0 to use the default.
+ *
+ * @return 0 on success; -ve on error:
+ * -EIO or -ETIMEDOUT - a register access failed.
+ *
+ * @ingroup fdriver
+ */
+int sdio_set_block_size(struct sdio_dev *fdev, int blksz)
+{
+ struct sdio_slot_priv *slotp = fdev->priv->slot->priv;
+ int ret;
+
+ os_mutex_lock(&slotp->card_mutex);
+ ret = sdio_func_set_block_size(fdev, blksz);
+ os_mutex_unlock(&slotp->card_mutex);
+
+ return ret;
+}
+
+/**
+ * Set the function as idle.
+ *
+ * When all functions are idle the SD bus will be idled.
+ *
+ * Functions are set as active (non-idle) when a command is started.
+ *
+ * @param fdev the SDIO device to set as idle.
+ *
+ * @see slot_driver::idle_bus.
+ *
+ * @ingroup fdriver
+ */
+void sdio_idle_function(struct sdio_dev *fdev)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ os_int_status_t istate;
+
+ os_spinlock_lock_intsave(&slotp->lock, &istate);
+
+ slotp->active &= ~(1 << fdev->function);
+ if (!slotp->active) {
+ slot_set_bus_freq(slot, SDD_BUS_FREQ_IDLE);
+ }
+
+ os_spinlock_unlock_intrestore(&slotp->lock, &istate);
+}
+
+/**
+ * Limit the bus frequency supported by a function.
+ *
+ * slotp->card_mutex must be held.
+ *
+ * @see sdio_set_max_bus_freq
+ */
+void sdio_func_set_max_bus_freq(struct sdio_dev *fdev, int max_freq)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ int freq;
+ int f;
+
+ if (max_freq == SDD_BUS_FREQ_DEFAULT) {
+ max_freq = slotp->max_card_freq;
+ }
+ fdevp->max_freq = max_freq;
+
+ freq = slotp->max_card_freq;
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ if (slotp->functions[f]) {
+ fdevp = slotp->functions[f]->priv;
+ if (fdevp->max_freq != 0 && fdevp->max_freq < freq) {
+ freq = fdevp->max_freq;
+ }
+ }
+ }
+ slot_set_max_bus_freq(slot, freq);
+}
+
+/**
+ * Limit the bus frequency supported by a function.
+ *
+ * The bus frequency used will be the minimum of:
+ * - the speed reported by the card,
+ * - the maximum the slot can support,
+ * - the value set by this function for any of the card's functions.
+ *
+ * If the frequency to be used is high speed (> 25 MHz), high speed
+ * mode will be enabled on the card.
+ *
+ * Callable from: thread context.
+ *
+ * @param fdev the SDIO device.
+ * @param max_freq maximum frequency in Hz, or 0 for the maximum
+ * reported by the card.
+ *
+ * @ingroup fdriver
+ */
+void sdio_set_max_bus_freq(struct sdio_dev *fdev, int max_freq)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ os_mutex_lock(&slotp->card_mutex);
+ sdio_func_set_max_bus_freq(fdev, max_freq);
+ os_mutex_unlock(&slotp->card_mutex);
+}
+
+/**
+ * Set the SDIO bus to 1 bit or 4 bit mode.
+ *
+ * Callable from: thread context.
+ *
+ * @param fdev the SDIO device.
+ * @param bus_width the bus width (1 or 4).
+ *
+ * @return 0 on success (or if the slot is in SPI mode).
+ * @return -EINVAL if the slot doesn't support the requested mode.
+ * @return -EIO, -ETIMEDOUT if an I/O error occured when writing the
+ * mode to the card.
+ *
+ * @ingroup fdriver
+ */
+int sdio_set_bus_width(struct sdio_dev *fdev, int bus_width)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ int ret;
+
+ if (bus_width != 1 && bus_width != 4) {
+ return -EINVAL;
+ }
+ if (bus_width > slot->caps.max_bus_width) {
+ return -EINVAL;
+ }
+ if (slot->type != SDD_SLOT_TYPE_SD) {
+ return 0;
+ }
+
+ os_mutex_lock(&slotp->card_mutex);
+
+ ret = slot_set_bus_width(slot, bus_width);
+
+ os_mutex_unlock(&slotp->card_mutex);
+
+ return ret;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_int.c b/unifi_hostsw_linux_147/sdioemb/sdio_int.c
new file mode 100644
index 0000000..997f64e
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_int.c
@@ -0,0 +1,107 @@
+/*
+ * Card interrupt management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "sdio_layer.h"
+
+/**
+ * Allow this SDIO device to receive card interrupt signals.
+ *
+ * This only affects the routing of card interrupts from the core.
+ *
+ * Callable from: any context.
+ *
+ * @param fdev the SDIO device to enable interrupt routing for.
+ *
+ * @note The core always sets the I/O Enable bits for all functions,
+ * so interrupts sources on the card should be enabled and disabled in
+ * a function specific manner by the function driver.
+ *
+ * @ingroup fdriver
+ */
+void sdio_enable_interrupt(struct sdio_dev *fdev)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ unsigned int_enabled;
+ os_int_status_t istate;
+
+ os_spinlock_lock_intsave(&slotp->lock, &istate);
+
+ int_enabled = slotp->int_enabled | (1 << fdev->function);
+ if (slotp->int_enabled == 0) {
+ slot->enable_card_int(slot);
+ }
+ slotp->int_enabled = int_enabled;
+
+ sdio_event_log(slot, SDD_EVENT_INT_UNMASKED, 1 << fdev->function);
+
+ os_spinlock_unlock_intrestore(&slotp->lock, &istate);
+}
+
+
+/**
+ * Prevent this SDIO device from receiving card interrupt signals.
+ *
+ * This only affects the routing of card interrupts from the core.
+ *
+ * Function drivers should ensure they clear any pending interrupts
+ * before calling this.
+ *
+ * Callable from: any context.
+ *
+ * @param fdev the SDIO device to disable interrupt routing for.
+ *
+ * @see sdio_enable_interrupt().
+ *
+ * @ingroup fdriver
+ */
+void sdio_disable_interrupt(struct sdio_dev *fdev)
+{
+ struct sdio_dev_priv *fdevp = fdev->priv;
+ struct sdio_slot *slot = fdevp->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+ unsigned int_enabled;
+ os_int_status_t istate;
+
+ os_spinlock_lock_intsave(&slotp->lock, &istate);
+
+ int_enabled = slotp->int_enabled & ~(1 << fdev->function);
+ if (int_enabled == 0) {
+ slot->disable_card_int(slot);
+ }
+ slotp->int_enabled = int_enabled;
+
+ sdio_event_log(slot, SDD_EVENT_INT_MASKED, 1 << fdev->function);
+
+ os_spinlock_unlock_intrestore(&slotp->lock, &istate);
+}
+
+/**
+ * Notify the SDIO layer that the card interrupt is asserted.
+ *
+ * Callable from: interrupt context.
+ *
+ * @param slot the slot with the asserted interrupt.
+ *
+ * @ingroup sdriver
+ */
+void sdio_interrupt(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int f;
+
+ sdio_event_log(slot, SDD_EVENT_CARD_INT);
+
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ struct sdio_dev *fdev = slotp->functions[f];
+ if (fdev && slotp->int_enabled & (1 << f)) {
+ fdev->driver->card_int_handler(fdev);
+ }
+ }
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_io.c b/unifi_hostsw_linux_147/sdioemb/sdio_io.c
new file mode 100644
index 0000000..fc41dd1
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_io.c
@@ -0,0 +1,443 @@
+/*
+ * Bus I/O operations.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <sdioemb/cspi.h>
+
+#include "sdio_layer.h"
+
+enum sdio_cmd_direction {
+ CMD_WRITE, CMD_READ,
+};
+
+static int cmd_status_to_errno(struct sdio_cmd *cmd)
+{
+ enum sdio_cmd_status status = cmd->status;
+
+ /* Check error bits in valid R5 responses. */
+ if (status == SDD_CMD_OK
+ && ((cmd->flags & SDD_CMD_FLAG_RESP_MASK) == SDD_CMD_FLAG_RESP_R5
+ || (cmd->flags & SDD_CMD_FLAG_RESP_MASK) == SDD_CMD_FLAG_RESP_R5B)) {
+ if (cmd->sdio.response.r5 & (SDIO_R5_OUT_OF_RANGE | SDIO_R5_FUNCTION_NUMBER)) {
+ return -EINVAL;
+ }
+ if (cmd->sdio.response.r5 & SDIO_R5_ERROR) {
+ return -EIO;
+ }
+ }
+
+ if (status & SDD_CMD_ERR_TIMEOUT) {
+ return -ETIMEDOUT;
+ }
+ if (status & (SDD_CMD_ERR_CRC | SDD_CMD_ERR_OTHER)) {
+ return -EIO;
+ }
+ if (status & SDD_CMD_ERR_NO_CARD) {
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static void wait_for_cmd_complete(struct sdio_cmd *cmd)
+{
+ os_semaphore_t *cmd_done_sem = cmd->priv;
+
+ os_semaphore_wait(cmd_done_sem);
+}
+
+static void cmd_callback(struct sdio_cmd *cmd)
+{
+ os_semaphore_t *cmd_done_sem = cmd->priv;
+
+ os_semaphore_post(cmd_done_sem);
+}
+
+static int start_cmd_and_wait(struct sdio_dev *fdev, struct sdio_cmd *cmd)
+{
+ os_semaphore_t cmd_done_sem;
+ int ret;
+
+ os_semaphore_init(&cmd_done_sem);
+
+ cmd->callback = cmd_callback;
+ cmd->priv = &cmd_done_sem;
+
+ ret = sdio_start_cmd(fdev, cmd);
+ if (ret) {
+ return ret;
+ }
+ wait_for_cmd_complete(cmd);
+
+ return 0;
+}
+
+static int sdio_cmd52(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data,
+ enum sdio_cmd_direction dir)
+{
+ struct sdio_cmd cmd;
+ int ret;
+
+ cmd.sdio.cmd = 52;
+ cmd.sdio.arg = SDIO_CMD52_ARG_FUNC(func) | SDIO_CMD52_ARG_ADDR(addr)
+ | (dir == CMD_WRITE ? SDIO_CMD52_ARG_WRITE | SDIO_CMD52_ARG_DATA(*data) : 0);
+ cmd.data = NULL;
+ cmd.flags = SDD_CMD_FLAG_RESP_R5;
+
+ ret = start_cmd_and_wait(fdev, &cmd);
+ if (ret) {
+ return ret;
+ }
+
+ if (cmd.status == SDD_CMD_OK) {
+ *data = SDIO_R5_DATA(cmd.sdio.response.r5);
+ }
+ return cmd_status_to_errno(&cmd);
+}
+
+int sdio_io_read8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data)
+{
+ return sdio_cmd52(fdev, func, addr, data, CMD_READ);
+}
+
+int sdio_io_write8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t data)
+{
+ return sdio_cmd52(fdev, func, addr, &data, CMD_WRITE);
+}
+
+static void sdio_io_abort(struct sdio_dev *fdev, int func)
+{
+ struct sdio_cmd cmd;
+
+ cmd.sdio.cmd = 52;
+ cmd.sdio.arg = SDIO_CMD52_ARG_FUNC(0) | SDIO_CMD52_ARG_ADDR(SDIO_CCCR_IO_ABORT)
+ | SDIO_CMD52_ARG_WRITE | SDIO_CMD52_ARG_DATA(func);
+ cmd.data = NULL;
+ cmd.flags = SDD_CMD_FLAG_RESP_R5 | SDD_CMD_FLAG_ABORT;
+
+ start_cmd_and_wait(fdev, &cmd);
+}
+
+static int sdio_cmd53(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data,
+ size_t len, enum sdio_cmd_direction dir)
+{
+ struct sdio_cmd cmd;
+ int count;
+ int ret;
+
+ if (len >= fdev->blocksize) {
+ count = len / fdev->blocksize;
+ } else {
+ count = len;
+ }
+
+ cmd.sdio.cmd = 53;
+ cmd.sdio.arg = SDIO_CMD53_ARG_FUNC(func) | SDIO_CMD53_ARG_ADDR(addr) | SDIO_CMD53_ARG_CNT(count)
+ | (dir == CMD_WRITE ? SDIO_CMD53_ARG_WRITE : 0)
+ | (len >= fdev->blocksize ? SDIO_CMD53_ARG_BLK_MODE : 0);
+ cmd.data = data;
+ cmd.len = len;
+ cmd.flags = (dir == CMD_READ
+ ? SDD_CMD_FLAG_RESP_R5 | SDD_CMD_FLAG_READ
+ : SDD_CMD_FLAG_RESP_R5B);
+
+ ret = start_cmd_and_wait(fdev, &cmd);
+ if (ret) {
+ return ret;
+ }
+ /*
+ * If the command completed with an error abort the data transfer
+ * with a write to the I/O Abort register, otherwise the transfer
+ * state of the card and the host is undetermined.
+ */
+ if (cmd.status != SDD_CMD_OK && cmd.status != SDD_CMD_ERR_NO_CARD) {
+ sdio_io_abort(fdev, func);
+ }
+
+ return cmd_status_to_errno(&cmd);
+}
+
+int sdio_io_write(struct sdio_dev *fdev, int func, uint32_t addr, const uint8_t *data, size_t len)
+{
+ int remainder = 0;
+ int ret;
+
+ if (len > fdev->blocksize) {
+ remainder = len % fdev->blocksize;
+ len -= remainder;
+ }
+
+ /* The slot drivers won't write to 'data' for a write command so
+ casting away the const is safe. */
+ ret = sdio_cmd53(fdev, func, addr, (uint8_t *)data, len, CMD_WRITE);
+ if (!ret && remainder) {
+ ret = sdio_cmd53(fdev, func, addr, (uint8_t *)data + len, remainder, CMD_WRITE);
+ }
+ return ret;
+}
+
+int sdio_io_read(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data, size_t len)
+{
+ int remainder = 0;
+ int ret;
+
+ if (len > fdev->blocksize) {
+ remainder = len % fdev->blocksize;
+ len -= remainder;
+ }
+
+ ret = sdio_cmd53(fdev, func, addr, data, len, CMD_READ);
+ if (!ret && remainder) {
+ ret = sdio_cmd53(fdev, func, addr, data + len, remainder, CMD_READ);
+ }
+ return ret;
+}
+
+static int cspi_word(struct sdio_dev *fdev, int func, uint32_t addr, uint16_t *word, uint8_t dir)
+{
+ struct sdio_cmd cmd;
+ int ret;
+
+ cmd.cspi.cmd = dir | CSPI_FUNC(func);
+ cmd.cspi.addr = addr;
+ cmd.cspi.val = *word;
+ cmd.data = NULL;
+ cmd.flags = SDD_CMD_FLAG_CSPI;
+
+ ret = start_cmd_and_wait(fdev, &cmd);
+ if (ret) {
+ return ret;
+ }
+ *word = cmd.cspi.val;
+ return cmd_status_to_errno(&cmd);
+}
+
+int cspi_io_read8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data)
+{
+ uint16_t word;
+ int ret;
+
+ ret = cspi_word(fdev, func, addr, &word, CSPI_READ);
+ *data = word & 0xff;
+ return ret;
+}
+
+int cspi_io_write8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t data)
+{
+ uint16_t word = data;
+
+ return cspi_word(fdev, func, addr, &word, CSPI_WRITE);
+}
+
+static int cspi_burst(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data, size_t len,
+ uint8_t dir)
+{
+ struct sdio_cmd cmd;
+ int ret;
+
+ cmd.cspi.cmd = dir | CSPI_BURST | CSPI_FUNC(func);
+ cmd.cspi.addr = addr;
+ cmd.data = data;
+ cmd.len = len;
+ cmd.flags = SDD_CMD_FLAG_CSPI;
+
+ ret = start_cmd_and_wait(fdev, &cmd);
+ if (ret) {
+ return ret;
+ }
+
+ return cmd_status_to_errno(&cmd);
+}
+
+int cspi_io_read(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data, size_t len)
+{
+ return cspi_burst(fdev, func, addr, data, len, CSPI_READ);
+}
+
+int cspi_io_write(struct sdio_dev *fdev, int func, uint32_t addr, const uint8_t *data, size_t len)
+{
+ return cspi_burst(fdev, func, addr, (uint8_t *)data, len, CSPI_WRITE);
+}
+
+
+/*
+ * The sdio_raw_*() functions bypass the command queues and send the
+ * command directly to the slot driver.
+ */
+
+static int start_raw_cmd_and_wait(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ os_semaphore_t cmd_done_sem;
+ int ret;
+
+ os_semaphore_init(&cmd_done_sem);
+
+ cmd->callback = cmd_callback;
+ cmd->priv = &cmd_done_sem;
+
+ ret = slot_start_cmd(slot, cmd);
+ if (ret) {
+ return ret;
+ }
+ wait_for_cmd_complete(cmd);
+
+ return 0;
+}
+
+
+int sdio_raw_cmd(struct sdio_slot *slot, uint8_t cmd_id, uint32_t arg, unsigned flags,
+ union sdio_response *response)
+{
+ struct sdio_cmd cmd;
+ int ret;
+
+ cmd.sdio.cmd = cmd_id;
+ cmd.sdio.arg = arg;
+ cmd.data = NULL;
+ cmd.flags = SDD_CMD_FLAG_RAW | flags;
+
+ ret = start_raw_cmd_and_wait(slot, &cmd);
+ if (ret) {
+ return ret;
+ }
+
+ if (cmd.status == SDD_CMD_OK) {
+ *response = cmd.sdio.response;
+ }
+ return cmd_status_to_errno(&cmd);
+}
+
+int cspi_raw_word_cmd(struct sdio_slot *slot, uint8_t cmd_id, uint32_t addr, uint16_t *word)
+{
+ struct sdio_cmd cmd;
+ int ret;
+
+ cmd.cspi.cmd = cmd_id;
+ cmd.cspi.addr = addr;
+ cmd.cspi.val = *word;
+ cmd.data = NULL;
+ cmd.flags = SDD_CMD_FLAG_RAW | SDD_CMD_FLAG_CSPI;
+
+ ret = start_raw_cmd_and_wait(slot, &cmd);
+ if (ret) {
+ return ret;
+ }
+ *word = cmd.cspi.val;
+ return cmd_status_to_errno(&cmd);
+}
+
+
+/**
+ * Read an 8 bit wide register.
+ *
+ * @param fdev SDIO function to read from.
+ * @param addr register address.
+ * @param val returns the value read.
+ *
+ * @return 0 on success.
+ * @return -EIO if a low-level transport error occurred (e.g., CRC error),
+ * @return -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+int sdio_read8(struct sdio_dev *fdev, uint32_t addr, uint8_t *val)
+{
+ return fdev->io->read8(fdev, fdev->function, addr, val);
+}
+
+/**
+ * Write an 8 bit wide register.
+ *
+ * @param fdev SDIO function to write to.
+ * @param addr register address.
+ * @param val value to write.
+ *
+ * @return 0 on success.
+ * @return -EIO if a low-level transport error occurred (e.g., CRC error),
+ * @return -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+int sdio_write8(struct sdio_dev *fdev, uint32_t addr, uint8_t val)
+{
+ return fdev->io->write8(fdev, fdev->function, addr, val);
+}
+
+/**
+ * Read an 8 bit wide function 0 register.
+ *
+ * @param fdev an SDIO function of the card.
+ * @param addr register address.
+ * @param val returns the value read.
+ *
+ * @return 0 on success.
+ * @return -EIO if a low-level transport error occurred (e.g., CRC error),
+ * @return -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+int sdio_f0_read8(struct sdio_dev *fdev, uint32_t addr, uint8_t *val)
+{
+ return fdev->io->read8(fdev, 0, addr, val);
+}
+
+/**
+ * Write an 8 bit wide function 0 register.
+ *
+ * @param fdev an SDIO function of the card.
+ * @param addr register address.
+ * @param val value to write.
+ *
+ * @return 0 on success.
+ * @return -EIO if a low-level transport error occurred (e.g., CRC error),
+ * @return -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+int sdio_f0_write8(struct sdio_dev *fdev, uint32_t addr, uint8_t val)
+{
+ return fdev->io->write8(fdev, 0, addr, val);
+}
+
+/**
+ * Read a buffer from an 8 bit wide card register/FIFO.
+ *
+ * @param fdev SDIO function to read from.
+ * @param addr register/FIFO address.
+ * @param data buffer to store the data read.
+ * @param len length of the buffer.
+ *
+ * @return 0 on success.
+ * @return -EIO if a low-level transport error occurred (e.g., CRC error).
+ * @return -ETIMEDOUT if no response or data was received.
+ *
+ * @ingroup fdriver
+ */
+int sdio_read(struct sdio_dev *fdev, uint32_t addr, void *data, size_t len)
+{
+ return fdev->io->read(fdev, fdev->function, addr, data, len);
+}
+
+/**
+ * Writes a buffer to an 8 bit wide card register/FIFO.
+ *
+ * @param fdev SDIO function to write to.
+ * @param addr register/FIFO address.
+ * @param data buffer of data to write.
+ * @param len length of the buffer.
+ *
+ * @return 0 on success.
+ * @return -EIO if a low-level transport error occurred (e.g., CRC error).
+ * @return -ETIMEDOUT if no response was received.
+ *
+ * @ingroup fdriver
+ */
+
+int sdio_write(struct sdio_dev *fdev, uint32_t addr, const void *data, size_t len)
+{
+ return fdev->io->write(fdev, fdev->function, addr, data, len);
+}
+
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_layer.h b/unifi_hostsw_linux_147/sdioemb/sdio_layer.h
new file mode 100644
index 0000000..c9547a1
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_layer.h
@@ -0,0 +1,120 @@
+/*
+ * Internal/private definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SDIO_LAYER_H
+#define _SDIO_LAYER_H
+
+#include <oska/all.h>
+
+#include <sdioemb/sdio.h>
+#include <sdioemb/sdio_api.h>
+#include <sdioemb/slot_api.h>
+
+#include "sdio_event_log.h"
+#include "sdio_config.h"
+
+#define SDD_MAX_FUNCTIONS (SDIO_MAX_FUNCTIONS + 1) /* extra for uif function */
+
+struct sdio_slot_priv {
+ int id;
+
+ unsigned card_present:1;
+ unsigned card_powered:1;
+
+ int num_functions;
+ struct sdio_dev *functions[SDD_MAX_FUNCTIONS];
+ int max_bus_width;
+ int max_card_freq;
+ int current_clock_freq;
+ unsigned supports_high_speed:1;
+
+ struct sdio_card_io_ops io_ops;
+
+ os_spinlock_t lock;
+
+ unsigned active;
+ unsigned power;
+ unsigned int_enabled;
+
+ int busy;
+ int last_function;
+#if SDD_CARD_IS_REMOVABLE
+ os_thread_t card_detect_thread;
+#endif
+ os_mutex_t card_mutex;
+
+#ifdef SDD_DEBUG_EVENT_LOG
+ struct sdio_event_log event_log;
+#endif
+};
+
+struct sdio_dev_priv {
+ struct sdio_slot *slot;
+ uint32_t cis_ptr;
+ int max_freq;
+ struct sdio_cmd *queued_cmd;
+};
+
+void slot_error(struct sdio_slot *slot, const char *fmt, ...);
+void slot_warning(struct sdio_slot *slot, const char *fmt, ...);
+void slot_info(struct sdio_slot *slot, const char *fmt, ...);
+void slot_debug(struct sdio_slot *slot, const char *fmt, ...);
+
+void sdio_core_init(void);
+struct sdio_dev *sdio_dev_alloc(struct sdio_slot *slot, int func);
+void sdio_dev_free(struct sdio_dev *fdev);
+int sdio_dev_add(struct sdio_dev *fdev);
+void sdio_dev_del(struct sdio_dev *fdev);
+
+int sdio_card_detect_init(struct sdio_slot *slot);
+void sdio_card_detect_exit(struct sdio_slot *slot);
+int sdio_card_start(struct sdio_slot *slot);
+void sdio_card_stop(struct sdio_slot *slot);
+void sdio_card_configure(struct sdio_slot *slot);
+
+int slot_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd);
+void slot_set_max_bus_freq(struct sdio_slot *slot, int freq);
+void slot_set_bus_freq(struct sdio_slot *slot, int freq);
+int slot_set_bus_width(struct sdio_slot *slot, int bus_width);
+
+int sdio_func_set_block_size(struct sdio_dev *fdev, int blksz);
+void sdio_func_set_max_bus_freq(struct sdio_dev *fdev, int max_freq);
+
+int sdio_cis_read_ptr_reg(struct sdio_dev *fdev, uint32_t addr, uint32_t *ptr);
+
+int sdio_raw_cmd(struct sdio_slot *slot, uint8_t cmd_id, uint32_t arg, unsigned flags,
+ union sdio_response *response);
+int cspi_raw_word_cmd(struct sdio_slot *slot, uint8_t cmd_id, uint32_t addr, uint16_t *word);
+
+int sdio_io_read8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data);
+int sdio_io_write8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t data);
+int sdio_io_read(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data, size_t len);
+int sdio_io_write(struct sdio_dev *fdev, int func, uint32_t addr, const uint8_t *data, size_t len);
+
+int cspi_io_read8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data);
+int cspi_io_write8(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t data);
+int cspi_io_read(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data, size_t len);
+int cspi_io_write(struct sdio_dev *fdev, int func, uint32_t addr, const uint8_t *data, size_t len);
+
+int cspi_is_enabled(struct sdio_slot *slot);
+int cspi_card_init(struct sdio_slot *slot);
+int cspi_enable(struct sdio_slot *slot);
+
+extern int sdd_card_poll_interval_ms;
+extern int sdd_max_bus_freq;
+extern int sdd_max_block_size;
+
+extern os_mutex_t sdio_core_mutex;
+
+/*
+ * Hooks for managing OS-specific device structures.
+ */
+int sdio_os_dev_add(struct sdio_dev *fdev);
+void sdio_os_dev_del(struct sdio_dev *fdev);
+
+#endif /* #ifndef _SDIO_LAYER_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_lx.c b/unifi_hostsw_linux_147/sdioemb/sdio_lx.c
new file mode 100644
index 0000000..33e8ad0
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_lx.c
@@ -0,0 +1,145 @@
+/*
+ * Linux kernel module support.
+ *
+ * Copyright (C) 2007-2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+
+#include "sdio_layer.h"
+
+int sdd_card_poll_interval_ms = 500;
+module_param_named(card_poll_interval, sdd_card_poll_interval_ms, int, 0644);
+MODULE_PARM_DESC(card_poll_interval, "interval (in ms) between card detect polls");
+
+int sdd_max_bus_freq = 0;
+module_param_named(max_bus_freq, sdd_max_bus_freq, int, 0444);
+MODULE_PARM_DESC(max_bus_freq, "maximum bus frequency (in Hz), or 0 for card's maximum");
+
+int sdd_max_block_size = 0;
+module_param_named(max_block_size, sdd_max_block_size, int, 0444);
+MODULE_PARM_DESC(max_block_size, "maximum block size, or 0 for the card's maximum");
+
+EXPORT_SYMBOL(sdio_driver_register);
+EXPORT_SYMBOL(sdio_driver_unregister);
+EXPORT_SYMBOL(sdio_set_block_size);
+EXPORT_SYMBOL(sdio_set_max_bus_freq);
+EXPORT_SYMBOL(sdio_set_bus_width);
+EXPORT_SYMBOL(sdio_enable_function);
+EXPORT_SYMBOL(sdio_disable_function);
+EXPORT_SYMBOL(sdio_idle_function);
+EXPORT_SYMBOL(sdio_enable_interrupt);
+EXPORT_SYMBOL(sdio_disable_interrupt);
+EXPORT_SYMBOL(sdio_cis_get_tuple);
+
+EXPORT_SYMBOL(sdio_read8);
+EXPORT_SYMBOL(sdio_write8);
+EXPORT_SYMBOL(sdio_f0_read8);
+EXPORT_SYMBOL(sdio_f0_write8);
+EXPORT_SYMBOL(sdio_read);
+EXPORT_SYMBOL(sdio_write);
+
+EXPORT_SYMBOL(sdio_slot_alloc);
+EXPORT_SYMBOL(sdio_slot_free);
+EXPORT_SYMBOL(sdio_slot_register);
+EXPORT_SYMBOL(sdio_slot_unregister);
+EXPORT_SYMBOL(sdio_card_inserted);
+EXPORT_SYMBOL(sdio_card_removed);
+EXPORT_SYMBOL(sdio_hard_reset);
+EXPORT_SYMBOL(sdio_interrupt);
+EXPORT_SYMBOL(sdio_cmd_complete);
+
+EXPORT_SYMBOL(sdio_power_on);
+EXPORT_SYMBOL(sdio_power_off);
+EXPORT_SYMBOL(sdio_suspend);
+EXPORT_SYMBOL(sdio_resume);
+
+/* Only for sdio_uif. */
+EXPORT_SYMBOL(slot_set_bus_freq);
+
+struct sdioe_dev {
+ struct device dev;
+};
+
+struct bus_type sdioe_bus_type = {
+ .name = "sdioemb",
+ /* Seems we can we get away with these being NULL since no drivers
+ are ever added to the bus. */
+ .match = NULL,
+ .probe = NULL,
+ .remove = NULL,
+};
+
+static void sdioe_device_release(struct device *dev)
+{
+ struct sdioe_dev *sdev = container_of(dev, struct sdioe_dev, dev);
+ kfree(sdev);
+}
+
+static struct sdioe_dev *sdioe_device_create(struct sdio_dev *fdev)
+{
+ struct sdio_slot *slot = fdev->priv->slot;
+ struct sdioe_dev *sdev;
+
+ sdev = kzalloc(sizeof(struct sdioe_dev), GFP_KERNEL);
+ if (sdev) {
+ snprintf(sdev->dev.bus_id, sizeof(sdev->dev.bus_id),
+ "%s.%d", slot->name, fdev->function);
+ sdev->dev.parent = NULL;
+ sdev->dev.bus = &sdioe_bus_type;
+ sdev->dev.release = sdioe_device_release;
+ }
+ return sdev;
+}
+
+int sdio_os_dev_add(struct sdio_dev *fdev)
+{
+ struct sdioe_dev *sdev;
+ int err = -ENOMEM;
+
+ sdev = sdioe_device_create(fdev);
+ if (sdev) {
+ err = device_register(&sdev->dev);
+ if (err < 0) {
+ kfree(sdev);
+ } else {
+ fdev->os_device = &sdev->dev;
+ }
+ }
+ return err;
+}
+
+void sdio_os_dev_del(struct sdio_dev *fdev)
+{
+ if (fdev->os_device) {
+ device_unregister(fdev->os_device);
+ fdev->os_device = NULL;
+ }
+}
+
+static int __init sdio_init(void)
+{
+ int err;
+
+ err = bus_register(&sdioe_bus_type);
+ if (err) {
+ return err;
+ }
+
+ sdio_core_init();
+ return 0;
+}
+module_init(sdio_init);
+
+static void __exit sdio_exit(void)
+{
+ bus_unregister(&sdioe_bus_type);
+}
+module_exit(sdio_exit);
+
+MODULE_DESCRIPTION("Embedded SDIO device driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_os_event_log_lx.c b/unifi_hostsw_linux_147/sdioemb/sdio_os_event_log_lx.c
new file mode 100644
index 0000000..467de78
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_os_event_log_lx.c
@@ -0,0 +1,153 @@
+/*
+ * Linux interface to the SDIO event log.
+ *
+ * The log is presented as text in /proc/driver/slot%d_event_log.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <sdioemb/cspi.h>
+#include "sdio_layer.h"
+
+#ifdef SDD_DEBUG_EVENT_LOG
+
+static void *sdio_event_log_start(struct seq_file *s, loff_t *pos)
+{
+ struct sdio_slot *slot = s->private;
+
+ return sdio_event_log_get_entry(slot, *pos);
+}
+
+static void *sdio_event_log_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ struct sdio_slot *slot = s->private;
+
+ (*pos)++;
+ return sdio_event_log_get_entry(slot, *pos);
+}
+
+static void sdio_event_log_stop(struct seq_file *s, void *v)
+{
+}
+
+static int sdio_event_log_show(struct seq_file *s, void *v)
+{
+ struct sdio_event_entry *e = v;
+
+ seq_printf(s, "%6u[%7lu.%03lu]: ",
+ e->seq_num, e->time_ms / 1000, e->time_ms % 1000);
+
+ switch (e->type) {
+ case SDD_EVENT_CMD:
+ if (e->cmd.flags & SDD_CMD_FLAG_CSPI) {
+ seq_printf(s, "CSPI cmd:%02x addr: %06x %s: %04x status: %02x resp: %02x\n",
+ e->cmd.cspi.cmd, e->cmd.cspi.addr,
+ e->cmd.cspi.cmd & CSPI_BURST ? "len" : "val", e->cmd.cspi.val,
+ e->cmd.status, e->cmd.cspi.response);
+ } else {
+ seq_printf(s, "CMD%02u arg: %08x stat: %02x resp: %08x\n",
+ e->cmd.sdio.cmd, e->cmd.sdio.arg, e->cmd.status, e->cmd.sdio.response.r1);
+ }
+#if SDD_DEBUG_DATA_BUFFER_LEN > 0
+ if (e->cmd.data.length != 0) {
+ unsigned int i;
+
+ for (i = 0; i < e->cmd.data.length; i++) {
+ if ((i % 16) == 0) {
+ seq_printf(s, " 0x%04X:", i);
+ }
+
+ seq_printf(s, " %02X", sdio_event_log_get_data(e, i));
+
+ if ((i % 16) == 15) {
+ seq_putc(s, '\n');
+ }
+ }
+ if ((i % 16) != 0) {
+ seq_putc(s, '\n');
+ }
+ }
+#endif
+ break;
+ case SDD_EVENT_CARD_INT:
+ seq_printf(s, "card interrupt\n");
+ break;
+ case SDD_EVENT_INT_MASKED:
+ seq_printf(s, "card interrupt masked: %02x\n", e->functions);
+ break;
+ case SDD_EVENT_INT_UNMASKED:
+ seq_printf(s, "card interrupt unmasked: %02x\n", e->functions);
+ break;
+ case SDD_EVENT_POWER_ON:
+ seq_printf(s, "power on\n");
+ break;
+ case SDD_EVENT_POWER_OFF:
+ seq_printf(s, "power off\n");
+ break;
+ case SDD_EVENT_RESET:
+ seq_printf(s, "hard reset\n");
+ break;
+ case SDD_EVENT_CLOCK_FREQ:
+ seq_printf(s, "clock frequency request: %d kHz\n", e->val / 1000);
+ break;
+ }
+
+ return 0;
+}
+
+static struct seq_operations sdio_event_log_seq_ops = {
+ .start = sdio_event_log_start,
+ .next = sdio_event_log_next,
+ .stop = sdio_event_log_stop,
+ .show = sdio_event_log_show,
+};
+
+static int sdio_event_log_proc_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ ret = seq_open(file, &sdio_event_log_seq_ops);
+ if (!ret) {
+ ((struct seq_file *)file->private_data)->private = PDE(inode)->data;
+ }
+ return ret;
+}
+
+static struct file_operations sdio_event_log_proc_ops = {
+ .owner = THIS_MODULE,
+ .open = sdio_event_log_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+void sdio_os_event_log_init(struct sdio_slot *slot)
+{
+ struct proc_dir_entry *proc_entry;
+ char path[32];
+
+ sprintf(path, "driver/slot%d_event_log", slot->priv->id);
+ proc_entry = create_proc_entry(path, 0444, NULL);
+ if (proc_entry) {
+ proc_entry->data = slot;
+ proc_entry->proc_fops = &sdio_event_log_proc_ops;
+ }
+}
+
+void sdio_os_event_log_deinit(struct sdio_slot *slot)
+{
+ char path[32];
+
+ sprintf(path, "driver/slot%d_event_log", slot->priv->id);
+ remove_proc_entry(path, NULL);
+}
+
+#endif /* #ifdef SDD_DEBUG_EVENT_LOG */
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_pm.c b/unifi_hostsw_linux_147/sdioemb/sdio_pm.c
new file mode 100644
index 0000000..1cba527
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_pm.c
@@ -0,0 +1,135 @@
+/*
+ * Power management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "sdio_layer.h"
+
+/**
+ * Request power to the card.
+ *
+ * If the card is not powered, apply power and re-initialize the card.
+ * No per-function state of the card is restored and the driver should
+ * re-enable the function and perform any other function specific
+ * initialization.
+ *
+ * This is called by the core before calling a function driver's
+ * probe() method.
+ *
+ * @param fdev the SDIO device requesting power.
+ *
+ * @ingroup fdriver
+ */
+void sdio_power_on(struct sdio_dev *fdev)
+{
+ struct sdio_slot *slot = fdev->priv->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ os_mutex_lock(&slotp->card_mutex);
+
+ slotp->power |= 1 << fdev->function;
+
+ if (!slotp->card_powered) {
+ sdio_card_start(slot);
+ sdio_card_configure(slot);
+ sdio_func_set_max_bus_freq(fdev, fdev->priv->max_freq);
+ }
+
+ os_mutex_unlock(&slotp->card_mutex);
+}
+
+/**
+ * Allow the card to be powered off.
+ *
+ * If no other function is requesting power, the card is powered
+ * off. The driver must call sdio_power_on() before performing any
+ * more I/O to the card.
+ *
+ * Interrupts are disabled by calling sdio_disable_interrupt() as the
+ * DAT1/INT line may no longer be pulled high when power is removed.
+ *
+ * This is called by the core after calling a function driver's
+ * remove() method.
+ *
+ * @param fdev the SDIO device not requiring power.
+ *
+ * @ingroup fdriver
+ */
+void sdio_power_off(struct sdio_dev *fdev)
+{
+ struct sdio_slot *slot = fdev->priv->slot;
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ sdio_disable_interrupt(fdev);
+
+ os_mutex_lock(&slotp->card_mutex);
+
+ slotp->power &= ~(1 << fdev->function);
+
+ if (!slotp->power && slotp->card_powered) {
+ sdio_card_stop(slot);
+ }
+
+ os_mutex_unlock(&slotp->card_mutex);
+}
+
+/**
+ * Notify the SDIO driver that the suspend event has been received.
+ *
+ * @param slot the slot being suspended.
+ *
+ * @ingroup sdriver
+ */
+void sdio_suspend(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int f;
+
+ /*
+ * Pass the event to all device drivers that
+ * have registered a suspend handler.
+ */
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ struct sdio_dev *fdev = slotp->functions[f];
+ if (fdev) {
+ if (fdev->driver) {
+ if (fdev->driver->suspend) {
+ fdev->driver->suspend(fdev);
+ }
+ }
+ }
+ }
+ slot_set_bus_freq(slot, SDD_BUS_FREQ_OFF);
+}
+
+
+/**
+ * Notify the SDIO driver that the resume event has been received.
+ *
+ * @param slot the slot being resumed.
+ *
+ * @ingroup sdriver
+ */
+void sdio_resume(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ int f;
+
+ /*
+ * Pass the event to all device drivers that
+ * have registered a resume handler.
+ */
+ for (f = 0; f < SDD_MAX_FUNCTIONS; f++) {
+ struct sdio_dev *fdev = slotp->functions[f];
+ if (fdev) {
+ if (fdev->driver) {
+ if (fdev->driver->resume) {
+ fdev->driver->resume(fdev);
+ }
+ }
+ }
+ }
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/sdio_slot.c b/unifi_hostsw_linux_147/sdioemb/sdio_slot.c
new file mode 100644
index 0000000..84f0379
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/sdio_slot.c
@@ -0,0 +1,293 @@
+/*
+ * Slot driver management.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include "sdio_config.h"
+#include "sdio_layer.h"
+
+/*
+ * A list of registered slots is kept so that: sdio_slot_unregister()
+ * can be called with an unregistered slot; and the slot's position in
+ * the slot list is the slot ID.
+ */
+struct sdio_slot *registered_slots[SDD_SLOTS_MAX];
+
+/*
+ * Add slot to registered slot list.
+ */
+static int slot_add(struct sdio_slot *slot)
+{
+ int i;
+
+ os_mutex_lock(&sdio_core_mutex);
+ for (i = 0; i < SDD_SLOTS_MAX; i++) {
+ if (registered_slots[i] == NULL) {
+ registered_slots[i] = slot;
+ slot->priv->id = i;
+ break;
+ }
+ }
+ os_mutex_unlock(&sdio_core_mutex);
+
+ if (i == SDD_SLOTS_MAX) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Remove slot from registered slot list.
+ */
+static int slot_del(struct sdio_slot *slot)
+{
+ int i;
+
+ os_mutex_lock(&sdio_core_mutex);
+ for (i = 0; i < SDD_SLOTS_MAX; i++) {
+ if (registered_slots[i] == slot) {
+ registered_slots[i] = NULL;
+ break;
+ }
+ }
+ os_mutex_unlock(&sdio_core_mutex);
+
+ if (i == SDD_SLOTS_MAX) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * Allocate and initialize and SDIO slot driver structure.
+ *
+ * Callable from: thread context.
+ *
+ * @param drv_data_size size of slot driver's drv_data.
+ *
+ * @return the allocated structure; or NULL if no memory could be
+ * allocated.
+ *
+ * @ingroup sdriver
+ */
+struct sdio_slot *sdio_slot_alloc(size_t drv_data_size)
+{
+ struct sdio_slot *slot;
+ struct sdio_slot_priv *slotp;
+
+ slot = os_alloc(sizeof(struct sdio_slot)
+ + sizeof(struct sdio_slot_priv)
+ + drv_data_size);
+ if (!slot)
+ return NULL;
+
+ slotp = slot->priv = (struct sdio_slot_priv *)&slot[1];
+ slot->drv_data = (uint8_t *)slot->priv + sizeof(struct sdio_slot_priv);
+
+ os_spinlock_init(&slotp->lock);
+ os_mutex_init(&slotp->card_mutex);
+
+ /* Sensible defaults for some capabilities. */
+ slot->caps.max_bus_freq = SDIO_CLOCK_FREQ_NORMAL_SPD;
+
+ return slot;
+}
+
+/**
+ * Free a slot_driver allocated with sdio_slot_alloc().
+ *
+ * Callable from: thread context.
+ *
+ * @param slot the slot driver to free.
+ *
+ * @ingroup sdriver
+ */
+void sdio_slot_free(struct sdio_slot *slot)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ os_spinlock_destroy(&slotp->lock);
+ os_free(slot);
+}
+
+
+/**
+ * Register a slot driver with the SDIO layer.
+ *
+ * Callable from: thread context.
+ *
+ * @param slot the slot driver to register.
+ *
+ * @return 0 on success; -ve on error: -ENOMEM - maximum number of
+ * slots are already registered.
+ *
+ * @see SDD_SLOTS_MAX
+ *
+ * @ingroup sdriver
+ */
+int sdio_slot_register(struct sdio_slot *slot)
+{
+ int ret;
+
+ ret = slot_add(slot);
+ if (ret < 0)
+ return ret;
+
+ sdio_event_log_init(slot);
+
+ ret = sdio_card_detect_init(slot);
+ if (ret) {
+ slot_del(slot);
+ sdio_event_log_deinit(slot);
+ return ret;
+ }
+
+ slot_info(NULL, "registered slot %s", slot->name);
+
+ return 0;
+}
+
+/**
+ * Unregister a slot driver from the SDIO layer.
+ *
+ * Callable from: thread context.
+ *
+ * @param slot the slot driver to unregister.
+ *
+ * @ingroup sdriver
+ */
+void sdio_slot_unregister(struct sdio_slot *slot)
+{
+ if (slot_del(slot) < 0) {
+ return;
+ }
+
+ slot_info(NULL, "unregister slot %s", slot->name);
+
+ sdio_card_detect_exit(slot);
+ sdio_event_log_deinit(slot);
+}
+
+/**
+ * Start a command after setting the bus to the active frequency (if necessary).
+ *
+ * @param slot the slot to perform the command.
+ * @param cmd the command to start.
+ *
+ * @return 0 on success.
+ * @return -EINVAL if the slot cannot handle the command.
+ */
+int slot_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ cmd->status = SDD_CMD_IN_PROGRESS;
+ sdio_event_log(slot, SDD_EVENT_CMD, cmd);
+
+ slot_set_bus_freq(slot, slot->clock_freq);
+ slot->clock_freq = slotp->current_clock_freq;
+
+ return slot->start_cmd(slot, cmd);
+}
+
+/**
+ * Set the maximum bus frequency for this slot.
+ *
+ * High speed mode is enabled (or disabled) on the card if required.
+ *
+ * @param slot the slot.
+ * @param max_freq maximum bus frequency in Hz.
+ */
+void slot_set_max_bus_freq(struct sdio_slot *slot, int freq)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_dev *f0 = slotp->functions[0];
+
+ if (slotp->supports_high_speed) {
+ if (freq > SDIO_CLOCK_FREQ_NORMAL_SPD
+ && slot->clock_freq <= SDIO_CLOCK_FREQ_NORMAL_SPD) {
+ f0->io->write8(f0, 0, SDIO_CCCR_HIGH_SPEED, SDIO_CCCR_HIGH_SPEED_EHS);
+ }
+ if (freq <= SDIO_CLOCK_FREQ_NORMAL_SPD
+ && slot->clock_freq > SDIO_CLOCK_FREQ_NORMAL_SPD) {
+ f0->io->write8(f0, 0, SDIO_CCCR_HIGH_SPEED, 0x00);
+ }
+ }
+
+ sdio_event_log(slot, SDD_EVENT_CLOCK_FREQ, freq);
+ slot->clock_freq = freq;
+}
+
+/**
+ * Set the bus frequency.
+ *
+ * @param slot the slot to perform the command.
+ * @param freq frequence value.
+ */
+void slot_set_bus_freq(struct sdio_slot *slot, int freq)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+
+ /* set clock rate and start it if it isn't already running at the
+ * correct speed. */
+
+ if (slotp->current_clock_freq != freq) {
+ if (slot->set_bus_freq != NULL) {
+ slotp->current_clock_freq = slot->set_bus_freq(slot, freq);
+ }
+ }
+}
+
+
+/**
+ * Set a slot's bus width.
+ *
+ * The requested width is set on both the host and the card.
+ *
+ * @param slot the slot.
+ * @param bus_width the new bus width.
+ *
+ * @return 0 on success
+ * @return -ve on failure.
+ */
+int slot_set_bus_width(struct sdio_slot *slot, int bus_width)
+{
+ struct sdio_slot_priv *slotp = slot->priv;
+ struct sdio_dev *f0 = slotp->functions[0];
+ int ret;
+ uint8_t bus_iface_cntl;
+
+ if (slot->set_bus_width) {
+ ret = slot->set_bus_width(slot, bus_width);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
+ ret = f0->io->read8(f0, 0, SDIO_CCCR_BUS_IFACE_CNTL, &bus_iface_cntl);
+ if (ret < 0) {
+ goto error;
+ }
+ if (bus_width == 4) {
+ bus_iface_cntl |= SDIO_CCCR_BUS_IFACE_CNTL_4BIT_BUS;
+ } else {
+ bus_iface_cntl &= ~SDIO_CCCR_BUS_IFACE_CNTL_4BIT_BUS;
+ }
+ ret = f0->io->write8(f0, 0, SDIO_CCCR_BUS_IFACE_CNTL, bus_iface_cntl);
+ if (ret < 0) {
+ goto error;
+ }
+
+ slot->bus_width = bus_width;
+ return 0;
+
+ error:
+ /* Try to recover from errors by restoring the old bus width. */
+ if (slot->set_bus_width) {
+ slot->set_bus_width(slot, slot->bus_width);
+ }
+ return ret;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx27.h b/unifi_hostsw_linux_147/sdioemb/slot_imx27.h
new file mode 100644
index 0000000..3aa2235
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx27.h
@@ -0,0 +1,86 @@
+/*
+ * i.MX27 SDHC definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_IMX27_H
+#define _SLOT_IMX27_H
+
+/*
+ * i.MX27 SDHC registers.
+ */
+
+#define SDHC_STR_STP_CLK 0x00
+# define STR_STP_CLK_MMCSD_RESET 0x0008
+# define STR_STP_CLK_START_CLK 0x0002
+# define STR_STP_CLK_STOP_CLK 0x0001
+
+#define SDHC_STATUS 0x04
+# define STATUS_CARD_PRESENCE 0x8000
+# define STATUS_SDIO_INT_ACTIVE 0x4000
+# define STATUS_END_CMD_RESP 0x2000
+# define STATUS_WRITE_OP_DONE 0x1000
+# define STATUS_READ_OP_DONE 0x0800
+# define STATUS_CARD_BUS_CLK_RUN 0x0100
+# define STATUS_APPL_BUFF_FF 0x0080
+# define STATUS_APPL_BUFF_FE 0x0040
+# define STATUS_RESP_CRC_ERR 0x0020
+# define STATUS_CRC_READ_ERR 0x0008
+# define STATUS_CRC_WRITE_ERR 0x0004
+# define STATUS_TIME_OUT_RESP 0x0002
+# define STATUS_TIME_OUT_READ 0x0001
+# define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP)
+# define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ)
+# define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK)
+
+#define SDHC_CLK_RATE 0x08
+
+#define SDHC_CMD_DAT_CTRL 0x0c /* CMD_DAT_CONT */
+# define CMD_DAT_CTRL_CMD_RESUME 0x8000
+# define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000
+# define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800
+# define CMD_DAT_CTRL_START_READ_WAIT 0x0400
+# define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200
+# define CMD_DAT_CTRL_INIT 0x0080
+# define CMD_DAT_CTRL_WRITE 0x0010
+# define CMD_DAT_CTRL_DATA_ENABLE 0x0008
+# define CMD_DAT_CTRL_RESP_NONE 0x0000
+# define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001
+# define CMD_DAT_CTRL_RESP_R2 0x0002
+# define CMD_DAT_CTRL_RESP_R3_R4 0x0003
+
+#define SDHC_RES_TO 0x10
+
+#define SDHC_READ_TO 0x14
+# define READ_TO_RECOMMENDED 0x2db4
+
+#define SDHC_BLK_LEN 0x18
+
+#define SDHC_NOB 0x1c
+
+#define SDHC_REV_NO 0x20
+
+#define SDHC_INT_CTRL 0x24 /* INT_CNTR */
+# define INT_CTRL_CARD_INSERTION_EN 0x8000
+# define INT_CTRL_SDIO_REMOVAL_EN 0x4000
+# define INT_CTRL_SDIO_IRQ_EN 0x2000
+# define INT_CTRL_DAT0_EN 0x1000
+# define INT_CTRL_BUF_READ_EN 0x0010
+# define INT_CTRL_BUF_WRITE_EN 0x0008
+# define INT_CTRL_END_CMD_RES 0x0004
+# define INT_CTRL_WRITE_OP_DONE 0x0002
+# define INT_CTRL_READ_OP_DONE 0x0001
+# define INT_CTRL_INT_EN_MASK 0xe01f
+
+#define SDHC_CMD 0x28
+
+#define SDHC_ARG 0x2c
+
+#define SDHC_RES_FIFO 0x34
+
+#define SDHC_BUFFER_ACCESS 0x38
+
+#endif /* #ifndef _SLOT_IMX27_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.c
new file mode 100644
index 0000000..f2b82ef
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.c
@@ -0,0 +1,547 @@
+/*
+ * Linux i.MX27 SDHC driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/kernel-compat.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/delay.h>
+#include <asm/arch/clock.h>
+
+#include "slot_imx27.h"
+#include "slot_imx27_lx.h"
+
+extern void gpio_sdhc_active(int module);
+extern void gpio_sdhc_inactive(int module);
+
+struct imx_sdio_controller {
+ struct platform_device *pdev;
+ struct resource * iomem_resource;
+ uint32_t base_phys;
+ void __iomem * base;
+ int irq;
+ enum mxc_clocks clock_id;
+ spinlock_t lock;
+ struct sdio_cmd * current_cmd;
+ int cur_bus_width;
+ uint32_t int_ctrl;
+ int dma;
+ enum dma_data_direction dma_dir;
+ dma_addr_t dma_addr;
+};
+
+static void imx_sdio_hw_enable_int(struct imx_sdio_controller *sdioc, uint32_t ints)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdioc->lock, flags);
+
+ sdioc->int_ctrl |= ints;
+ writel(sdioc->int_ctrl, sdioc->base + SDHC_INT_CTRL);
+
+ spin_unlock_irqrestore(&sdioc->lock, flags);
+}
+
+static void imx_sdio_hw_disable_int(struct imx_sdio_controller *sdioc, uint32_t ints)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdioc->lock, flags);
+
+ sdioc->int_ctrl &= ~ints;
+ writel(sdioc->int_ctrl, sdioc->base + SDHC_INT_CTRL);
+
+ spin_unlock_irqrestore(&sdioc->lock, flags);
+}
+
+static void imx_sdio_hw_start_clock(struct imx_sdio_controller *sdioc)
+{
+ writel(STR_STP_CLK_START_CLK, sdioc->base + SDHC_STR_STP_CLK);
+}
+
+static void imx_sdio_hw_stop_clock(struct imx_sdio_controller *sdioc)
+{
+ unsigned timeout = 10000; /* 10 ms */
+
+ writel(STR_STP_CLK_STOP_CLK, sdioc->base + SDHC_STR_STP_CLK);
+
+ /* Wait for clock to stop. */
+ do {
+ uint32_t stat = readl(sdioc->base + SDHC_STATUS);
+ if (!(stat & STATUS_CARD_BUS_CLK_RUN)) {
+ break;
+ }
+ udelay(1);
+ } while (--timeout);
+
+ if (timeout == 0) {
+ dev_err(&sdioc->pdev->dev, "unable to stop MMCCLK\n");
+ }
+}
+
+static int imx_sdio_hw_set_clock_rate(struct imx_sdio_controller *sdioc, int freq)
+{
+ int clk_in = mxc_get_clocks(sdioc->clock_id);
+ uint32_t prescaler, clk_div;
+ int f;
+
+ prescaler = 0;
+ while (prescaler <= 16) {
+ for (clk_div = 1; clk_div <= 0xF; clk_div++) {
+ if (prescaler != 0) {
+ f = (clk_in / (clk_div + 1)) / (prescaler * 2);
+ } else {
+ f = clk_in / (clk_div + 1);
+ }
+ if (f <= freq) {
+ break;
+ }
+ }
+ if (clk_div < 0x10) {
+ break;
+ }
+ if (prescaler == 0) {
+ prescaler = 1;
+ } else {
+ prescaler <<= 1;
+ }
+ }
+
+ imx_sdio_hw_stop_clock(sdioc);
+ writel((prescaler << 4) | clk_div, sdioc->base + SDHC_CLK_RATE);
+ imx_sdio_hw_start_clock(sdioc);
+
+ return f;
+}
+
+static void imx_sdio_hw_start(struct imx_sdio_controller *sdioc)
+{
+ int i;
+
+ gpio_sdhc_active(sdioc->pdev->id);
+ mxc_clks_enable(sdioc->clock_id);
+
+ /* Reset the controller. */
+ writel(STR_STP_CLK_MMCSD_RESET, sdioc->base + SDHC_STR_STP_CLK);
+ writel(STR_STP_CLK_MMCSD_RESET | STR_STP_CLK_STOP_CLK, sdioc->base + SDHC_STR_STP_CLK);
+ for (i = 0; i < 8; i++) {
+ writel(STR_STP_CLK_STOP_CLK, sdioc->base + SDHC_STR_STP_CLK);
+ }
+
+ writel(64, sdioc->base + SDHC_RES_TO);
+ writel(READ_TO_RECOMMENDED, sdioc->base + SDHC_READ_TO);
+
+ imx_sdio_hw_enable_int(sdioc, INT_CTRL_END_CMD_RES);
+}
+
+static void imx_sdio_hw_stop(struct imx_sdio_controller *sdioc)
+{
+ imx_sdio_hw_disable_int(sdioc, INT_CTRL_INT_EN_MASK);
+ imx_sdio_hw_stop_clock(sdioc);
+
+ mxc_clks_disable(sdioc->clock_id);
+ gpio_sdhc_inactive(sdioc->pdev->id);
+}
+
+static uint32_t imx_sdio_hw_read_status_and_clear(struct imx_sdio_controller *sdioc)
+{
+ uint32_t status;
+
+ status = readl(sdioc->base + SDHC_STATUS);
+ writel(status, sdioc->base + SDHC_STATUS);
+ return status;
+}
+
+static uint32_t imx_sdio_hw_response_r1(struct imx_sdio_controller *sdioc)
+{
+ uint32_t r0, r1, r2;
+ r0 = readl(sdioc->base + SDHC_RES_FIFO);
+ r1 = readl(sdioc->base + SDHC_RES_FIFO);
+ r2 = readl(sdioc->base + SDHC_RES_FIFO);
+ return ((r0 & 0xff) << 24) | (r1 << 8) | (r2 >> 8);
+}
+
+static void imx_sdio_cmd_complete(struct sdio_slot *slot, uint32_t status)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+
+ /* Check status for error bits. */
+ if (status & STATUS_ERR_MASK) {
+ if (status & STATUS_TIME_OUT_RESP) {
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ } else if (status & STATUS_RESP_CRC_ERR) {
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ } else if (status & STATUS_ERR_DATA_MASK) {
+ if (status & STATUS_TIME_OUT_READ) {
+ cmd->status = SDD_CMD_ERR_DAT_TIMEOUT;
+ } else {
+ cmd->status = SDD_CMD_ERR_DAT_CRC;
+ }
+ }
+ } else {
+ cmd->status = SDD_CMD_OK;
+ }
+
+ if (cmd->data) {
+ mxc_dma_disable(sdioc->dma);
+ dma_unmap_single(&sdioc->pdev->dev, sdioc->dma_addr,
+ sdioc->current_cmd->len, sdioc->dma_dir);
+ }
+
+ /* Read response if it's valid. */
+ if (!(cmd->status & SDD_CMD_ERR_CMD)) {
+ switch (cmd->flags & SDD_CMD_FLAG_RESP_MASK) {
+ case SDD_CMD_FLAG_RESP_NONE:
+ break;
+ case SDD_CMD_FLAG_RESP_R1:
+ case SDD_CMD_FLAG_RESP_R1B:
+ case SDD_CMD_FLAG_RESP_R4:
+ case SDD_CMD_FLAG_RESP_R5:
+ case SDD_CMD_FLAG_RESP_R5B:
+ case SDD_CMD_FLAG_RESP_R6:
+ cmd->sdio.response.r1 = imx_sdio_hw_response_r1(sdioc);
+ break;
+ default:
+ dev_err(&sdioc->pdev->dev, "response format not supported\n");
+ }
+ }
+
+ sdio_cmd_complete(slot, cmd);
+}
+
+irqreturn_t imx_sdio_int_handler(int irq, void *dev_id)
+{
+ struct sdio_slot *slot = dev_id;
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+ uint32_t status;
+
+ status = imx_sdio_hw_read_status_and_clear(sdioc);
+
+ if (status & STATUS_SDIO_INT_ACTIVE) {
+ uint32_t int_ctrl = readl(sdioc->base + SDHC_INT_CTRL);
+ if (int_ctrl & INT_CTRL_SDIO_IRQ_EN) {
+ sdio_interrupt(slot);
+ }
+ }
+
+ if (status & STATUS_END_CMD_RESP) {
+ if (!cmd->data) {
+ imx_sdio_cmd_complete(slot, status);
+ }
+ }
+
+ if (status & STATUS_WRITE_OP_DONE) {
+ imx_sdio_hw_disable_int(sdioc, INT_CTRL_WRITE_OP_DONE);
+ imx_sdio_cmd_complete(slot, status);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void imx_sdio_dma_int_handler(void *devid, int error, unsigned int cnt)
+{
+ struct sdio_slot *slot = devid;
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ uint32_t status;
+
+ status = imx_sdio_hw_read_status_and_clear(sdioc);
+
+ /* For write operations, wait for WRITE_OP_DONE by enabling the
+ * interrupt if required. */
+ if (!error && sdioc->dma_dir == DMA_TO_DEVICE && !(status & STATUS_WRITE_OP_DONE)) {
+ imx_sdio_hw_enable_int(sdioc, INT_CTRL_WRITE_OP_DONE);
+ } else {
+ imx_sdio_cmd_complete(slot, status);
+ }
+}
+
+static void imx_sdio_setup_dma(struct sdio_slot *slot)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ mxc_dma_device_t dma_id = 0;
+
+ mxc_dma_free(sdioc->dma);
+ if (sdioc->pdev->id == 0) {
+ if (slot->bus_width == 4) {
+ dma_id = MXC_DMA_MMC1_WIDTH_4;
+ } else {
+ dma_id = MXC_DMA_MMC1_WIDTH_1;
+ }
+ } else {
+ if (slot->bus_width == 4) {
+ dma_id = MXC_DMA_MMC2_WIDTH_4;
+ } else {
+ dma_id = MXC_DMA_MMC2_WIDTH_1;
+ }
+ }
+ sdioc->dma = mxc_dma_request(dma_id, slot->name);
+ if (sdioc->dma < 0) {
+ dev_err(&sdioc->pdev->dev, "cannot allocate DMA channel\n");
+ }
+ mxc_dma_callback_set(sdioc->dma, imx_sdio_dma_int_handler, slot);
+}
+
+static int imx_sdio_set_bus_freq(struct sdio_slot *slot, int clk)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ if (clk == SDD_BUS_FREQ_OFF || clk == SDD_BUS_FREQ_IDLE) {
+ imx_sdio_hw_stop_clock(sdioc);
+ return 0;
+ }
+ return imx_sdio_hw_set_clock_rate(sdioc, clk);
+}
+
+static int imx_sdio_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ uint32_t nob, blk_len, cmd_dat_ctrl = 0;
+
+ sdioc->current_cmd = cmd;
+
+ if (sdioc->cur_bus_width != slot->bus_width) {
+ imx_sdio_setup_dma(slot);
+ }
+
+ /* The first command (which will always be a CMD0) must be
+ * preceeded by at least 64 clocks. */
+ if (cmd->sdio.cmd == 0) {
+ cmd_dat_ctrl |= CMD_DAT_CTRL_INIT;
+ }
+
+ if (slot->bus_width == 4) {
+ cmd_dat_ctrl |= CMD_DAT_CTRL_BUS_WIDTH_4;
+ }
+
+ switch (cmd->flags & SDD_CMD_FLAG_RESP_MASK) {
+ case SDD_CMD_FLAG_RESP_NONE:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_NONE;
+ break;
+ case SDD_CMD_FLAG_RESP_R1:
+ case SDD_CMD_FLAG_RESP_R1B:
+ case SDD_CMD_FLAG_RESP_R5:
+ case SDD_CMD_FLAG_RESP_R5B:
+ case SDD_CMD_FLAG_RESP_R6:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_R1_R5_R6;
+ break;
+ case SDD_CMD_FLAG_RESP_R2:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_R2;
+ break;
+ case SDD_CMD_FLAG_RESP_R3:
+ case SDD_CMD_FLAG_RESP_R4:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_R3_R4;
+ break;
+ }
+
+ if (cmd->data) {
+ mxc_dma_requestbuf_t dma_request;
+
+ cmd_dat_ctrl |= CMD_DAT_CTRL_DATA_ENABLE;
+ cmd_dat_ctrl |= (cmd->flags & SDD_CMD_FLAG_READ) ? 0 : CMD_DAT_CTRL_WRITE;
+
+ if (cmd->len < cmd->owner->blocksize) {
+ blk_len = cmd->len;
+ nob = 1;
+ } else {
+ blk_len = cmd->owner->blocksize;
+ nob = cmd->len / blk_len;
+ }
+
+ sdioc->dma_dir = (cmd->flags & SDD_CMD_FLAG_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ sdioc->dma_addr = dma_map_single(&sdioc->pdev->dev, cmd->data, cmd->len, sdioc->dma_dir);
+
+ if (sdioc->dma_dir == DMA_FROM_DEVICE) {
+ dma_request.src_addr = sdioc->base_phys + SDHC_BUFFER_ACCESS;
+ dma_request.dst_addr = sdioc->dma_addr;
+ dma_request.num_of_bytes = cmd->len;
+ mxc_dma_config(sdioc->dma, &dma_request, 1, MXC_DMA_MODE_READ);
+ } else {
+ dma_request.src_addr = sdioc->dma_addr;
+ dma_request.dst_addr = sdioc->base_phys + SDHC_BUFFER_ACCESS;
+ dma_request.num_of_bytes = cmd->len;
+ mxc_dma_config(sdioc->dma, &dma_request, 1, MXC_DMA_MODE_WRITE);
+ }
+ mxc_dma_enable(sdioc->dma);
+ } else {
+ nob = blk_len = 0;
+ }
+
+ /* Start the command. */
+ if (blk_len) {
+ writel(blk_len, sdioc->base + SDHC_BLK_LEN);
+ }
+ if (nob) {
+ writel(nob, sdioc->base + SDHC_NOB);
+ }
+ writel(cmd->sdio.cmd, sdioc->base + SDHC_CMD);
+ writel(cmd->sdio.arg, sdioc->base + SDHC_ARG);
+ writel(cmd_dat_ctrl, sdioc->base + SDHC_CMD_DAT_CTRL);
+
+ return 0;
+}
+
+static int imx_sdio_card_present(struct sdio_slot *slot)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct imx_sdio_plat_data *pdata = sdioc->pdev->dev.platform_data;
+
+ return pdata->card_present(sdioc->pdev);
+}
+
+static int imx_sdio_card_power(struct sdio_slot *slot, enum sdio_power power)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct imx_sdio_plat_data *pdata = sdioc->pdev->dev.platform_data;
+
+ return pdata->card_power(sdioc->pdev, power);
+}
+
+static void imx_sdio_enable_card_int(struct sdio_slot *slot)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ imx_sdio_hw_enable_int(sdioc, INT_CTRL_SDIO_IRQ_EN);
+}
+
+static void imx_sdio_disable_card_int(struct sdio_slot *slot)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ imx_sdio_hw_disable_int(sdioc, INT_CTRL_SDIO_IRQ_EN);
+}
+
+static int imx_sdio_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct imx_sdio_plat_data *pdata = dev->platform_data;
+ struct sdio_slot *slot;
+ struct imx_sdio_controller *sdioc;
+ struct resource *res;
+ int len, ret;
+
+ slot = sdio_slot_alloc(sizeof(struct imx_sdio_controller));
+ if (!slot) {
+ return -ENOMEM;
+ }
+ dev_set_drvdata(dev, slot);
+
+ strcpy(slot->name, dev->bus_id);
+ slot->set_bus_freq = imx_sdio_set_bus_freq;
+ slot->start_cmd = imx_sdio_start_cmd;
+ slot->card_present = imx_sdio_card_present;
+ slot->card_power = imx_sdio_card_power;
+ slot->enable_card_int = imx_sdio_enable_card_int;
+ slot->disable_card_int = imx_sdio_disable_card_int;
+
+ slot->caps.max_bus_width = pdata->max_bus_width;
+
+ sdioc = slot->drv_data;
+
+ sdioc->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ len = res->end - res->start + 1;
+ sdioc->iomem_resource = request_mem_region(res->start, len, "slot_imx27");
+ if (!sdioc->iomem_resource) {
+ dev_err(dev, "memory range %08lx-%08lx in use\n", res->start, res->end);
+ ret = -EBUSY;
+ goto err_mem_res;
+ }
+ sdioc->base_phys = res->start;
+ sdioc->base = ioremap(sdioc->base_phys, len);
+ if (!sdioc->base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ sdioc->irq = platform_get_irq(pdev, 0);
+ ret = request_irq(sdioc->irq, imx_sdio_int_handler, 0, slot->name, slot);
+ if (ret) {
+ dev_err(dev, "irq %d in use\n", sdioc->irq);
+ goto err_irq;
+ }
+
+ if (pdev->id == 0) {
+ sdioc->clock_id = SDHC1_CLK;
+ } else {
+ sdioc->clock_id = SDHC2_CLK;
+ }
+
+ spin_lock_init(&sdioc->lock);
+
+ imx_sdio_hw_start(sdioc);
+
+ ret = sdio_slot_register(slot);
+ if (ret) {
+ goto err_register;
+ }
+
+ return 0;
+
+ err_register:
+ imx_sdio_hw_stop(sdioc);
+ free_irq(sdioc->irq, slot);
+ err_irq:
+ iounmap(sdioc->base);
+ err_ioremap:
+ release_resource(sdioc->iomem_resource);
+ err_mem_res:
+ sdio_slot_free(slot);
+ return ret;
+}
+
+static int imx_sdio_remove(struct device *dev)
+{
+ struct sdio_slot *slot = dev_get_drvdata(dev);
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ sdio_slot_unregister(slot);
+
+ imx_sdio_hw_stop(sdioc);
+
+ mxc_dma_free(sdioc->dma);
+ free_irq(sdioc->irq, slot);
+ iounmap(sdioc->base);
+
+ release_resource(sdioc->iomem_resource);
+
+ sdio_slot_free(slot);
+
+ return 0;
+}
+
+static struct device_driver imx27_sdio_driver = {
+ .name = "imx27-sdio",
+ .bus = &platform_bus_type,
+ .probe = imx_sdio_probe,
+ .remove = imx_sdio_remove,
+};
+
+static int __init slot_imx27_init(void)
+{
+ return driver_register(&imx27_sdio_driver);
+}
+
+static void __exit slot_imx27_exit(void)
+{
+ driver_unregister(&imx27_sdio_driver);
+}
+
+module_init(slot_imx27_init);
+module_exit(slot_imx27_exit);
+
+MODULE_DESCRIPTION("i.MX27 SDHC slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.h b/unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.h
new file mode 100644
index 0000000..d5037aa
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx27_lx.h
@@ -0,0 +1,20 @@
+/*
+ * Linux i.MX27 slot driver platform data definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_IMX27_LX_H
+#define _SLOT_IMX27_LX_H
+
+#include <sdioemb/slot_api.h>
+
+struct imx_sdio_plat_data {
+ int max_bus_width;
+ int (*card_power)(struct platform_device *, enum sdio_power);
+ int (*card_present)(struct platform_device *);
+};
+
+#endif /* #ifndef _SLOT_IMX27_LX_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx27ads_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_imx27ads_lx.c
new file mode 100644
index 0000000..3e07419
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx27ads_lx.c
@@ -0,0 +1,141 @@
+/*
+ * Freescale i.MX27 ADS SDHC driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <asm/arch/pmic_power.h>
+
+#include "slot_imx27_lx.h"
+
+static int imx27ads_sdio_card_present(struct platform_device *pdev)
+{
+ uint16_t bstat;
+
+ bstat = readw(PBC_BSTAT1_REG);
+ if (pdev->id == 0) {
+ return !(bstat & PBC_BSTAT_SD1_DET);
+ } else {
+ return !(bstat & PBC_BSTAT_SD2_DET);
+ }
+}
+
+static int imx27ads_sdio_card_power(struct platform_device *pdev, enum sdio_power power)
+{
+ t_regulator_voltage voltage;
+
+ switch (power) {
+ case SDIO_POWER_OFF:
+ if (pdev->id == 0) {
+ pmic_power_regulator_set_lp_mode(REGU_VMMC1,
+ LOW_POWER_EN);
+ pmic_power_regulator_off(REGU_VMMC1);
+ } else {
+ pmic_power_regulator_set_lp_mode(REGU_VMMC2,
+ LOW_POWER_EN);
+ pmic_power_regulator_off(REGU_VMMC2);
+ }
+ dev_dbg(&pdev->dev, "power off\n");
+ break;
+ case SDIO_POWER_3V3:
+ if (pdev->id == 0) {
+ voltage.vmmc1 = VMMC1_3V;
+ pmic_power_regulator_set_voltage(REGU_VMMC1, voltage);
+ pmic_power_regulator_set_lp_mode(REGU_VMMC1,
+ LOW_POWER_DISABLED);
+ pmic_power_regulator_on(REGU_VMMC1);
+ } else {
+ voltage.vmmc2 = VMMC2_3V;
+ pmic_power_regulator_set_voltage(REGU_VMMC2, voltage);
+ pmic_power_regulator_set_lp_mode(REGU_VMMC2,
+ LOW_POWER_DISABLED);
+ pmic_power_regulator_on(REGU_VMMC2);
+ }
+ dev_dbg(&pdev->dev, "power on\n");
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct resource sdhc1_resources[] = {
+ {
+ .start = SDHC1_BASE_ADDR,
+ .end = SDHC1_BASE_ADDR + SZ_4K -1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDHC1,
+ .end = INT_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct imx_sdio_plat_data sdhc1_plat_data = {
+ .max_bus_width = 4,
+ .card_present = imx27ads_sdio_card_present,
+ .card_power = imx27ads_sdio_card_power,
+};
+
+static struct resource sdhc2_resources[] = {
+ {
+ .start = SDHC2_BASE_ADDR,
+ .end = SDHC2_BASE_ADDR + SZ_4K -1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDHC2,
+ .end = INT_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct imx_sdio_plat_data sdhc2_plat_data = {
+ .max_bus_width = 4,
+ .card_present = imx27ads_sdio_card_present,
+ .card_power = imx27ads_sdio_card_power,
+};
+
+static struct platform_device imx27ads_sdio_devices[] = {
+ {
+ .name = "imx27-sdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sdhc1_resources),
+ .resource = sdhc1_resources,
+ .dev = {
+ .platform_data = &sdhc1_plat_data,
+ },
+ },
+ {
+ .name = "imx27-sdio",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sdhc2_resources),
+ .resource = sdhc2_resources,
+ .dev = {
+ .platform_data = &sdhc2_plat_data,
+ },
+ },
+};
+
+static int __init slot_imx27ads_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(imx27ads_sdio_devices); i++) {
+ platform_device_register(&imx27ads_sdio_devices[i]);
+ }
+ return 0;
+}
+
+module_init(slot_imx27ads_init);
+
+MODULE_DESCRIPTION("Freescale i.MX27 ADS SDIO slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx31.h b/unifi_hostsw_linux_147/sdioemb/slot_imx31.h
new file mode 100644
index 0000000..b11894a
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx31.h
@@ -0,0 +1,86 @@
+/*
+ * i.MX31 SDHC definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_IMX31_H
+#define _SLOT_IMX31_H
+
+/*
+ * i.MX31 SDHC registers.
+ */
+
+#define SDHC_STR_STP_CLK 0x00
+# define STR_STP_CLK_MMCSD_RESET 0x0008
+# define STR_STP_CLK_START_CLK 0x0002
+# define STR_STP_CLK_STOP_CLK 0x0001
+
+#define SDHC_STATUS 0x04
+# define STATUS_CARD_PRESENCE 0x8000
+# define STATUS_SDIO_INT_ACTIVE 0x4000
+# define STATUS_END_CMD_RESP 0x2000
+# define STATUS_WRITE_OP_DONE 0x1000
+# define STATUS_READ_OP_DONE 0x0800
+# define STATUS_CARD_BUS_CLK_RUN 0x0100
+# define STATUS_APPL_BUFF_FF 0x0080
+# define STATUS_APPL_BUFF_FE 0x0040
+# define STATUS_RESP_CRC_ERR 0x0020
+# define STATUS_CRC_READ_ERR 0x0008
+# define STATUS_CRC_WRITE_ERR 0x0004
+# define STATUS_TIME_OUT_RESP 0x0002
+# define STATUS_TIME_OUT_READ 0x0001
+# define STATUS_ERR_CMD_MASK (STATUS_RESP_CRC_ERR | STATUS_TIME_OUT_RESP)
+# define STATUS_ERR_DATA_MASK (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR | STATUS_TIME_OUT_READ)
+# define STATUS_ERR_MASK (STATUS_ERR_CMD_MASK | STATUS_ERR_DATA_MASK)
+
+#define SDHC_CLK_RATE 0x08
+
+#define SDHC_CMD_DAT_CTRL 0x0c /* CMD_DAT_CONT */
+# define CMD_DAT_CTRL_CMD_RESUME 0x8000
+# define CMD_DAT_CTRL_CMD_RESP_LONG_OFF 0x1000
+# define CMD_DAT_CTRL_STOP_READ_WAIT 0x0800
+# define CMD_DAT_CTRL_START_READ_WAIT 0x0400
+# define CMD_DAT_CTRL_BUS_WIDTH_4 0x0200
+# define CMD_DAT_CTRL_INIT 0x0080
+# define CMD_DAT_CTRL_WRITE 0x0010
+# define CMD_DAT_CTRL_DATA_ENABLE 0x0008
+# define CMD_DAT_CTRL_RESP_NONE 0x0000
+# define CMD_DAT_CTRL_RESP_R1_R5_R6 0x0001
+# define CMD_DAT_CTRL_RESP_R2 0x0002
+# define CMD_DAT_CTRL_RESP_R3_R4 0x0003
+
+#define SDHC_RES_TO 0x10
+
+#define SDHC_READ_TO 0x14
+# define READ_TO_RECOMMENDED 0x2db4
+
+#define SDHC_BLK_LEN 0x18
+
+#define SDHC_NOB 0x1c
+
+#define SDHC_REV_NO 0x20
+
+#define SDHC_INT_CTRL 0x24 /* INT_CNTR */
+# define INT_CTRL_CARD_INSERTION_EN 0x8000
+# define INT_CTRL_SDIO_REMOVAL_EN 0x4000
+# define INT_CTRL_SDIO_IRQ_EN 0x2000
+# define INT_CTRL_DAT0_EN 0x1000
+# define INT_CTRL_BUF_READ_EN 0x0010
+# define INT_CTRL_BUF_WRITE_EN 0x0008
+# define INT_CTRL_END_CMD_RES 0x0004
+# define INT_CTRL_WRITE_OP_DONE 0x0002
+# define INT_CTRL_READ_OP_DONE 0x0001
+# define INT_CTRL_INT_EN_MASK 0xe01f
+
+#define SDHC_CMD 0x28
+
+#define SDHC_ARG 0x2c
+
+#define SDHC_RES_FIFO 0x34
+
+#define SDHC_BUFFER_ACCESS 0x38
+
+#endif /* #ifndef _SLOT_IMX31_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.c
new file mode 100644
index 0000000..131fa2e
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.c
@@ -0,0 +1,602 @@
+/*
+ * Linux i.MX27 SDHC driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/kernel-compat.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/delay.h>
+#include <asm/arch/clock.h>
+#include <linux/platform_device.h>
+
+
+#include "sdio_layer.h"
+#include "slot_imx31.h"
+#include "slot_imx31_lx.h"
+
+#define MMC_BUS_WIDTH_4 4
+#define SDHC_SD_WML 64
+#define SDHC_MMC_WML 16
+
+extern void gpio_sdhc_active(int module);
+extern void gpio_sdhc_inactive(int module);
+
+struct imx_sdio_controller {
+ struct platform_device *pdev;
+ struct resource * iomem_resource;
+ uint32_t base_phys;
+ void __iomem * base;
+ int irq;
+ enum mxc_clocks clock_id;
+ spinlock_t lock;
+ struct sdio_cmd * current_cmd;
+ int cur_bus_width;
+ uint32_t int_ctrl;
+ int dma;
+ enum dma_data_direction dma_dir;
+ dma_addr_t dma_addr;
+};
+
+static void imx_sdio_hw_enable_int(struct imx_sdio_controller *sdioc, uint32_t ints)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdioc->lock, flags);
+
+ sdioc->int_ctrl |= ints;
+ writel(sdioc->int_ctrl, sdioc->base + SDHC_INT_CTRL);
+
+ spin_unlock_irqrestore(&sdioc->lock, flags);
+}
+
+static void imx_sdio_hw_disable_int(struct imx_sdio_controller *sdioc, uint32_t ints)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdioc->lock, flags);
+
+ sdioc->int_ctrl &= ~ints;
+ writel(sdioc->int_ctrl, sdioc->base + SDHC_INT_CTRL);
+
+ spin_unlock_irqrestore(&sdioc->lock, flags);
+}
+
+static void imx_sdio_hw_start_clock(struct imx_sdio_controller *sdioc)
+{
+ writel(STR_STP_CLK_START_CLK, sdioc->base + SDHC_STR_STP_CLK);
+}
+
+static void imx_sdio_hw_stop_clock(struct imx_sdio_controller *sdioc)
+{
+ unsigned timeout = 10000; /* 10 ms */
+
+ writel(STR_STP_CLK_STOP_CLK, sdioc->base + SDHC_STR_STP_CLK);
+
+ /* Wait for clock to stop. */
+ do {
+ uint32_t stat = readl(sdioc->base + SDHC_STATUS);
+ if (!(stat & STATUS_CARD_BUS_CLK_RUN)) {
+ break;
+ }
+ udelay(1);
+ } while (--timeout);
+
+ if (timeout == 0) {
+ dev_err(&sdioc->pdev->dev, "unable to stop MMCCLK\n");
+ }
+}
+
+static int imx_sdio_hw_set_clock_rate(struct imx_sdio_controller *sdioc, int freq)
+{
+ int clk_in = mxc_get_clocks(sdioc->clock_id);
+ uint32_t prescaler, clk_div;
+ int f;
+
+ dev_dbg(&sdioc->pdev->dev, "freq = %d, clk_in = %d\n", freq, clk_in);
+
+ prescaler = 0;
+ while (prescaler <= 16) {
+ for (clk_div = 1; clk_div <= 0xF; clk_div++) {
+ if (prescaler != 0) {
+ f = (clk_in / (clk_div + 1)) / (prescaler * 2);
+ } else {
+ f = clk_in / (clk_div + 1);
+ }
+ if (f <= freq) {
+ break;
+ }
+ }
+ if (clk_div < 0x10) {
+ break;
+ }
+ if (prescaler == 0) {
+ prescaler = 1;
+ } else {
+ prescaler <<= 1;
+ }
+ }
+ dev_dbg(&sdioc->pdev->dev, "prescaler = 0x%x, divider = 0x%x, f = %d\n", prescaler, clk_div, f);
+
+ imx_sdio_hw_stop_clock(sdioc);
+ writel((prescaler << 4) | clk_div, sdioc->base + SDHC_CLK_RATE);
+ imx_sdio_hw_start_clock(sdioc);
+
+ return f;
+}
+
+static void imx_sdio_hw_start(struct imx_sdio_controller *sdioc)
+{
+ int i;
+
+ printk("PPP: sw_pad_sd1_cmd:%08x\n", readl(IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x168));
+ printk("PPP: sw_pad_sd1_data1:%08x\n", readl(IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x16C));
+ gpio_sdhc_active(sdioc->pdev->id);
+ writel(0x1a569485, IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x168);
+ writel(0x0a5295a5, IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x16C);
+ printk("PPP: sw_pad_sd1_cmd:%08x\n", readl(IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x168));
+ printk("PPP: sw_pad_sd1_data1:%08x\n", readl(IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x16C));
+ mxc_clks_enable(sdioc->clock_id);
+ printk("PPP: sw_pad_sd1_cmd:%08x\n", readl(IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x168));
+ printk("PPP: sw_pad_sd1_data1:%08x\n", readl(IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x16C));
+
+ /* Reset the controller. */
+ writel(STR_STP_CLK_MMCSD_RESET, sdioc->base + SDHC_STR_STP_CLK);
+ writel(STR_STP_CLK_MMCSD_RESET | STR_STP_CLK_STOP_CLK, sdioc->base + SDHC_STR_STP_CLK);
+ for (i = 0; i < 8; i++) {
+ writel(STR_STP_CLK_STOP_CLK, sdioc->base + SDHC_STR_STP_CLK);
+ }
+
+ writel(64, sdioc->base + SDHC_RES_TO);
+ writel(READ_TO_RECOMMENDED, sdioc->base + SDHC_READ_TO);
+
+ imx_sdio_hw_enable_int(sdioc, INT_CTRL_END_CMD_RES);
+}
+
+static void imx_sdio_hw_stop(struct imx_sdio_controller *sdioc)
+{
+ imx_sdio_hw_disable_int(sdioc, INT_CTRL_INT_EN_MASK);
+ imx_sdio_hw_stop_clock(sdioc);
+
+ mxc_clks_disable(sdioc->clock_id);
+ gpio_sdhc_inactive(sdioc->pdev->id);
+}
+
+static uint32_t imx_sdio_hw_read_status_and_clear(struct imx_sdio_controller *sdioc)
+{
+ uint32_t status;
+
+ status = readl(sdioc->base + SDHC_STATUS);
+ writel(status, sdioc->base + SDHC_STATUS);
+ return status;
+}
+
+static uint32_t imx_sdio_hw_response_r1(struct imx_sdio_controller *sdioc)
+{
+ uint32_t r0, r1, r2;
+ r0 = readl(sdioc->base + SDHC_RES_FIFO);
+ r1 = readl(sdioc->base + SDHC_RES_FIFO);
+ r2 = readl(sdioc->base + SDHC_RES_FIFO);
+ return ((r0 & 0xff) << 24) | (r1 << 8) | (r2 >> 8);
+}
+
+static void imx_sdio_cmd_complete(struct sdio_slot *slot, uint32_t status)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+
+ /* Check status for error bits. */
+ if (status & STATUS_ERR_MASK) {
+ if (status & STATUS_TIME_OUT_RESP) {
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ } else if (status & STATUS_RESP_CRC_ERR) {
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ } else if (status & STATUS_ERR_DATA_MASK) {
+ if (status & STATUS_TIME_OUT_READ) {
+ cmd->status = SDD_CMD_ERR_DAT_TIMEOUT;
+ } else {
+ cmd->status = SDD_CMD_ERR_DAT_CRC;
+ }
+ }
+ } else {
+ cmd->status = SDD_CMD_OK;
+ }
+
+ if (cmd->data) {
+ mxc_dma_stop(sdioc->dma);
+ dma_unmap_single(&sdioc->pdev->dev, sdioc->dma_addr, sdioc->current_cmd->len,
+ sdioc->dma_dir);
+ }
+
+ /* Read response if it's valid. */
+ if (!(cmd->status & SDD_CMD_ERR_CMD)) {
+ switch (cmd->flags & SDD_CMD_FLAG_RESP_MASK) {
+ case SDD_CMD_FLAG_RESP_NONE:
+ break;
+ case SDD_CMD_FLAG_RESP_R1:
+ case SDD_CMD_FLAG_RESP_R1B:
+ case SDD_CMD_FLAG_RESP_R4:
+ case SDD_CMD_FLAG_RESP_R5:
+ case SDD_CMD_FLAG_RESP_R5B:
+ case SDD_CMD_FLAG_RESP_R6:
+ cmd->sdio.response.r1 = imx_sdio_hw_response_r1(sdioc);
+ break;
+ default:
+ dev_err(&sdioc->pdev->dev, "response format not supported\n");
+ }
+ }
+
+ sdio_cmd_complete(slot, cmd);
+}
+
+irqreturn_t imx_sdio_int_handler(int irq, void *dev_id)
+{
+ struct sdio_slot *slot = dev_id;
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+ uint32_t status;
+
+ status = imx_sdio_hw_read_status_and_clear(sdioc);
+
+ if (status & STATUS_SDIO_INT_ACTIVE) {
+ uint32_t int_ctrl = readl(sdioc->base + SDHC_INT_CTRL);
+ if (int_ctrl & INT_CTRL_SDIO_IRQ_EN) {
+ sdio_interrupt(slot);
+ }
+ }
+
+ if (status & STATUS_END_CMD_RESP) {
+ if (!cmd->data) {
+ imx_sdio_cmd_complete(slot, status);
+ }
+ }
+
+ if (status & STATUS_WRITE_OP_DONE) {
+ imx_sdio_hw_disable_int(sdioc, INT_CTRL_WRITE_OP_DONE);
+ imx_sdio_cmd_complete(slot, status);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void imx_sdio_dma_int_handler(void *devid)
+{
+ struct sdio_slot *slot = devid;
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ uint32_t status;
+
+ status = imx_sdio_hw_read_status_and_clear(sdioc);
+
+ /* For write operations, wait for WRITE_OP_DONE by enabling the
+ * interrupt if required. */
+ if (sdioc->dma_dir == DMA_TO_DEVICE && !(status & STATUS_WRITE_OP_DONE)) {
+ imx_sdio_hw_enable_int(sdioc, INT_CTRL_WRITE_OP_DONE);
+ } else {
+ imx_sdio_cmd_complete(slot, status);
+ }
+}
+
+static void imx_sdio_setup_dma(struct sdio_slot *slot)
+{
+#if 0
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ mxc_dma_device_t dma_id = 0;
+
+ mxc_dma_free(sdioc->dma);
+ if (sdioc->pdev->id == 0) {
+ if (slot->bus_width == 4) {
+ dma_id = MXC_DMA_MMC1_WIDTH_4;
+ } else {
+ dma_id = MXC_DMA_MMC1_WIDTH_1;
+ }
+ } else {
+ if (slot->bus_width == 4) {
+ dma_id = MXC_DMA_MMC2_WIDTH_4;
+ } else {
+ dma_id = MXC_DMA_MMC2_WIDTH_1;
+ }
+ }
+ sdioc->dma = mxc_dma_request(dma_id, slot->name);
+ if (sdioc->dma < 0) {
+ dev_err(&sdioc->pdev->dev, "cannot allocate DMA channel\n");
+ }
+ mxc_dma_callback_set(sdioc->dma, imx_sdio_dma_int_handler, slot);
+#endif
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ sdioc->dma = 0;
+ if ((mxc_request_dma(&sdioc->dma, sdioc->pdev->name)) < 0) {
+ dev_err(&sdioc->pdev->dev, "cannot allocate DMA channel\n");
+ }
+
+ mxc_dma_set_callback(sdioc->dma, imx_sdio_dma_int_handler, (void *)slot);
+
+
+}
+
+static int imx_sdio_set_bus_freq(struct sdio_slot *slot, int clk)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ if (clk == SDD_BUS_FREQ_OFF || clk == SDD_BUS_FREQ_IDLE) {
+ imx_sdio_hw_stop_clock(sdioc);
+ return 0;
+ }
+ return imx_sdio_hw_set_clock_rate(sdioc, clk);
+}
+
+static int imx_sdio_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ uint32_t nob, blk_len, cmd_dat_ctrl = 0;
+
+// printk("PPP:imx_sdio_start_cmd->enter:%d, %d\n", cmd->len, cmd->owner->blocksize);
+ sdioc->current_cmd = cmd;
+
+ if (sdioc->cur_bus_width != slot->bus_width) {
+ //imx_sdio_setup_dma(slot);
+ }
+
+ /* The first command (which will always be a CMD0) must be
+ * preceeded by at least 64 clocks. */
+ if (cmd->sdio.cmd == 0) {
+ cmd_dat_ctrl |= CMD_DAT_CTRL_INIT;
+ }
+
+ if (slot->bus_width == 4) {
+ cmd_dat_ctrl |= CMD_DAT_CTRL_BUS_WIDTH_4;
+ }
+
+ switch (cmd->flags & SDD_CMD_FLAG_RESP_MASK) {
+ case SDD_CMD_FLAG_RESP_NONE:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_NONE;
+ break;
+ case SDD_CMD_FLAG_RESP_R1:
+ case SDD_CMD_FLAG_RESP_R1B:
+ case SDD_CMD_FLAG_RESP_R5:
+ case SDD_CMD_FLAG_RESP_R5B:
+ case SDD_CMD_FLAG_RESP_R6:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_R1_R5_R6;
+ break;
+ case SDD_CMD_FLAG_RESP_R2:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_R2;
+ break;
+ case SDD_CMD_FLAG_RESP_R3:
+ case SDD_CMD_FLAG_RESP_R4:
+ cmd_dat_ctrl |= CMD_DAT_CTRL_RESP_R3_R4;
+ break;
+ }
+
+ if (cmd->data) {
+ dma_request_t dma_request;
+ dma_channel_params params;
+
+ // printk("PPP:There's data\n");
+ cmd_dat_ctrl |= CMD_DAT_CTRL_DATA_ENABLE;
+ cmd_dat_ctrl |= (cmd->flags & SDD_CMD_FLAG_READ) ? 0 : CMD_DAT_CTRL_WRITE;
+
+ if (cmd->len < cmd->owner->blocksize) {
+ blk_len = cmd->len;
+ nob = 1;
+ } else {
+ blk_len = cmd->owner->blocksize;
+ nob = cmd->len / blk_len;
+ }
+
+ sdioc->dma_dir = (cmd->flags & SDD_CMD_FLAG_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ sdioc->dma_addr = dma_map_single(&sdioc->pdev->dev, cmd->data, cmd->len, sdioc->dma_dir);
+
+ if (sdioc->dma_dir == DMA_FROM_DEVICE) {
+ // printk("PPP:Read\n");
+ dma_request.destAddr = (void*)sdioc->dma_addr;
+ dma_request.count = cmd->len;
+ params.transfer_type = per_2_emi;
+
+ } else {
+ // printk("PPP:Write\n");
+ dma_request.sourceAddr = (void*)sdioc->dma_addr;
+ dma_request.count = cmd->len;
+ params.transfer_type = emi_2_per;
+
+ }
+ if (slot->bus_width == MMC_BUS_WIDTH_4) {
+ params.watermark_level = SDHC_SD_WML;
+ } else {
+ params.watermark_level = SDHC_MMC_WML;
+ }
+ params.peripheral_type = MMC;
+ params.per_address = sdioc->base_phys + SDHC_BUFFER_ACCESS;
+ params.event_id = DMA_REQ_SDHC1;
+ params.bd_number = 1 /* host->dma_size / 256 */ ;
+ params.word_size = TRANSFER_32BIT;
+ params.callback = imx_sdio_dma_int_handler;
+ params.arg = slot;
+ mxc_dma_setup_channel(sdioc->dma, &params);
+ dma_request.count = cmd->len;
+ mxc_dma_set_config(sdioc->dma, &dma_request, 0);
+ mxc_dma_start(sdioc->dma);
+
+ } else {
+ nob = blk_len = 0;
+ }
+// printk("PPP:blk_len:%d, nob:%d, cmd:%08x, arg:%08x, ctrl:%08x\n",blk_len, nob, cmd->cmd, cmd->arg, cmd_dat_ctrl);
+
+ /* Start the command. */
+ if (blk_len) {
+ writel(blk_len, sdioc->base + SDHC_BLK_LEN);
+ }
+ if (nob) {
+ writel(nob, sdioc->base + SDHC_NOB);
+ }
+ writel(cmd->sdio.cmd, sdioc->base + SDHC_CMD);
+ writel(cmd->sdio.arg, sdioc->base + SDHC_ARG);
+ writel(cmd_dat_ctrl, sdioc->base + SDHC_CMD_DAT_CTRL);
+
+ return 0;
+}
+
+static int imx_sdio_card_present(struct sdio_slot *slot)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct imx_sdio_plat_data *pdata = sdioc->pdev->dev.platform_data;
+
+ return pdata->card_present(sdioc->pdev);
+}
+
+static int imx_sdio_card_power(struct sdio_slot *slot, enum sdio_power power)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+ struct imx_sdio_plat_data *pdata = sdioc->pdev->dev.platform_data;
+
+ return pdata->card_power(sdioc->pdev, power);
+}
+
+static void imx_sdio_enable_card_int(struct sdio_slot *slot)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ imx_sdio_hw_enable_int(sdioc, INT_CTRL_SDIO_IRQ_EN);
+}
+
+static void imx_sdio_disable_card_int(struct sdio_slot *slot)
+{
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ imx_sdio_hw_disable_int(sdioc, INT_CTRL_SDIO_IRQ_EN);
+}
+
+static int imx_sdio_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct imx_sdio_plat_data *pdata = dev->platform_data;
+ struct sdio_slot *slot;
+ struct imx_sdio_controller *sdioc;
+ struct resource *res;
+ int len, ret;
+
+ printk("PPP: sdio_probe\n");
+ slot = sdio_slot_alloc(sizeof(struct imx_sdio_controller));
+ if (!slot) {
+ return -ENOMEM;
+ }
+ dev_set_drvdata(dev, slot);
+
+ strcpy(slot->name, dev->bus_id);
+ slot->set_bus_freq = imx_sdio_set_bus_freq;
+ slot->start_cmd = imx_sdio_start_cmd;
+ slot->card_present = imx_sdio_card_present;
+ slot->card_power = imx_sdio_card_power;
+ slot->enable_card_int = imx_sdio_enable_card_int;
+ slot->disable_card_int = imx_sdio_disable_card_int;
+
+ slot->caps.max_bus_width = pdata->max_bus_width;
+
+ sdioc = slot->drv_data;
+
+ sdioc->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ len = res->end - res->start + 1;
+ sdioc->iomem_resource = request_mem_region(res->start, len, "slot_imx31");
+ if (!sdioc->iomem_resource) {
+ dev_err(dev, "memory range %08lx-%08lx in use\n", res->start, res->end);
+ ret = -EBUSY;
+ goto err_mem_res;
+ }
+ sdioc->base_phys = res->start;
+ sdioc->base = ioremap(sdioc->base_phys, len);
+ if (!sdioc->base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ sdioc->irq = platform_get_irq(pdev, 0);
+ ret = request_irq(sdioc->irq, imx_sdio_int_handler, 0, slot->name, slot);
+ if (ret) {
+ dev_err(dev, "irq %d in use\n", sdioc->irq);
+ goto err_irq;
+ }
+ imx_sdio_setup_dma(slot);
+
+ if (pdev->id == 0) {
+ sdioc->clock_id = SDHC1_CLK;
+ } else {
+ sdioc->clock_id = SDHC2_CLK;
+ }
+
+ spin_lock_init(&sdioc->lock);
+
+ imx_sdio_hw_start(sdioc);
+
+ ret = sdio_slot_register(slot);
+ if (ret) {
+ goto err_register;
+ }
+
+ return 0;
+
+ err_register:
+ imx_sdio_hw_stop(sdioc);
+ free_irq(sdioc->irq, slot);
+ err_irq:
+ iounmap(sdioc->base);
+ err_ioremap:
+ release_resource(sdioc->iomem_resource);
+ err_mem_res:
+ sdio_slot_free(slot);
+ return ret;
+}
+
+static int imx_sdio_remove(struct device *dev)
+{
+ struct sdio_slot *slot = dev_get_drvdata(dev);
+ struct imx_sdio_controller *sdioc = slot->drv_data;
+
+ sdio_slot_unregister(slot);
+
+ imx_sdio_hw_stop(sdioc);
+
+ mxc_free_dma(sdioc->dma);
+ free_irq(sdioc->irq, slot);
+ iounmap(sdioc->base);
+
+ release_resource(sdioc->iomem_resource);
+
+ sdio_slot_free(slot);
+
+ return 0;
+}
+
+static struct device_driver imx31_sdio_driver = {
+ .name = "imx31-sdio",
+ //.name = "mxcmci",
+ .bus = &platform_bus_type,
+ .probe = imx_sdio_probe,
+ .remove = imx_sdio_remove,
+};
+
+static int __init slot_imx31_init(void)
+{
+ printk("PPP: Reistering slot\n");
+ return driver_register(&imx31_sdio_driver);
+}
+
+static void __exit slot_imx31_exit(void)
+{
+ driver_unregister(&imx31_sdio_driver);
+}
+
+module_init(slot_imx31_init);
+module_exit(slot_imx31_exit);
+
+MODULE_DESCRIPTION("i.MX31 SDHC slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.h b/unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.h
new file mode 100644
index 0000000..8be35ed
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx31_lx.h
@@ -0,0 +1,20 @@
+/*
+ * Linux i.MX27 slot driver platform data definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_IMX31_LX_H
+#define _SLOT_IMX31_LX_H
+
+#include "sdio_layer.h"
+
+struct imx_sdio_plat_data {
+ int max_bus_width;
+ int (*card_power)(struct platform_device *, enum sdio_power);
+ int (*card_present)(struct platform_device *);
+};
+
+#endif /* #ifndef _SLOT_IMX31_LX_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_imx31ads_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_imx31ads_lx.c
new file mode 100644
index 0000000..233e052
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_imx31ads_lx.c
@@ -0,0 +1,162 @@
+/*
+ * Freescale i.MX27 ADS SDHC driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+//#include <asm/arch/mxc_pm.h>
+#include "../drivers/mxc/mc13783_legacy/module/mc13783_power.h"
+#include "sdio_layer.h"
+#include "slot_imx31_lx.h"
+extern unsigned int sdhc_get_card_det_status(struct device *dev);
+
+#define SD_3_0V 7
+
+static int imx31ads_sdio_card_present(struct platform_device *pdev)
+{
+// return sdhc_get_card_det_status(&pdev->dev);
+ return pdev->id == 0 ? 1 : 0;
+}
+
+static int imx31ads_sdio_card_power(struct platform_device *pdev, enum sdio_power power)
+{
+
+ switch (power) {
+ case SDIO_POWER_OFF:
+ if (pdev->id == 0) {
+ mc13783_power_conf_regu(REGU_VMMC1, false, true);
+ mc13783_power_regu_en(REGU_VMMC1, false);
+ } else {
+ mc13783_power_conf_regu(REGU_VMMC2, false, true);
+ mc13783_power_regu_en(REGU_VMMC2, false);
+
+ }
+ dev_dbg(&pdev->dev, "power off\n");
+ break;
+ case SDIO_POWER_3V3:
+ if (pdev->id == 0) {
+ mc13783_power_set_regu(REGU_VMMC1,
+ SD_3_0V);
+ mc13783_power_conf_regu(REGU_VMMC1, false, false);
+ mc13783_power_regu_en(REGU_VMMC1, true);
+
+ } else {
+ mc13783_power_set_regu(REGU_VMMC2,
+ SD_3_0V);
+ mc13783_power_conf_regu(REGU_VMMC2, false, false);
+ mc13783_power_regu_en(REGU_VMMC2, true);
+
+ }
+ dev_dbg(&pdev->dev, "power on\n");
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void imx31ads_sdio_release(struct device *dev)
+{
+ /* No resources have been allocated. */
+}
+
+static struct resource sdhc1_resources[] = {
+ {
+ .start = MMC_SDHC1_BASE_ADDR,
+ .end = MMC_SDHC1_BASE_ADDR + SZ_16K -1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MMC_SDHC1,
+ .end = INT_MMC_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct imx_sdio_plat_data sdhc1_plat_data = {
+ .max_bus_width = 4,
+ .card_present = imx31ads_sdio_card_present,
+ .card_power = imx31ads_sdio_card_power,
+};
+
+static struct resource sdhc2_resources[] = {
+ {
+ .start = MMC_SDHC2_BASE_ADDR,
+ .end = MMC_SDHC2_BASE_ADDR + SZ_16K -1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MMC_SDHC2,
+ .end = INT_MMC_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct imx_sdio_plat_data sdhc2_plat_data = {
+ .max_bus_width = 4,
+ .card_present = imx31ads_sdio_card_present,
+ .card_power = imx31ads_sdio_card_power,
+};
+
+static struct platform_device imx31ads_sdio_devices[] = {
+ {
+ .name = "imx31-sdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sdhc1_resources),
+ .resource = sdhc1_resources,
+ .dev = {
+ .platform_data = &sdhc1_plat_data,
+ .release = imx31ads_sdio_release,
+ },
+ },
+ {
+ .name = "imx31-sdio",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sdhc2_resources),
+ .resource = sdhc2_resources,
+ .dev = {
+ .platform_data = &sdhc2_plat_data,
+ .release = imx31ads_sdio_release,
+ },
+ },
+};
+
+static int __init slot_imx31ads_init(void)
+{
+ int i, ret;
+
+ //sdhc_init_card_det(0);
+ for (i = 0; i < ARRAY_SIZE(imx31ads_sdio_devices); i++) {
+ ret = platform_device_register(&imx31ads_sdio_devices[i]);
+ if (ret) {
+ while (--i >= 0) {
+ platform_device_unregister(&imx31ads_sdio_devices[i]);
+ }
+ break;
+ }
+ }
+ return ret;
+}
+
+static void __exit slot_imx31ads_exit(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(imx31ads_sdio_devices); i++) {
+ platform_device_unregister(&imx31ads_sdio_devices[i]);
+ }
+}
+
+module_init(slot_imx31ads_init);
+module_exit(slot_imx31ads_exit);
+
+MODULE_DESCRIPTION("Freescale i.MX31 ADS SDIO slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_pxa27x.h b/unifi_hostsw_linux_147/sdioemb/slot_pxa27x.h
new file mode 100644
index 0000000..cca853a
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_pxa27x.h
@@ -0,0 +1,70 @@
+/*
+ * PXA27x MMC/SD controller definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_PXA27X_H
+#define _SLOT_PXA27X_H
+
+#define PXA27X_MMC_MMCLK_BASE_FREQ 19500000
+#define PXA27X_MMC_FIFO_SIZE 32
+
+#define STOP_CLOCK (1 << 0)
+#define START_CLOCK (2 << 0)
+
+#define STAT_END_CMD_RES (1 << 13)
+#define STAT_PRG_DONE (1 << 12)
+#define STAT_DATA_TRAN_DONE (1 << 11)
+#define STAT_CLK_EN (1 << 8)
+#define STAT_RECV_FIFO_FULL (1 << 7)
+#define STAT_XMIT_FIFO_EMPTY (1 << 6)
+#define STAT_RES_CRC_ERR (1 << 5)
+#define STAT_SPI_READ_ERROR_TOKEN (1 << 4)
+#define STAT_CRC_READ_ERROR (1 << 3)
+#define STAT_CRC_WRITE_ERROR (1 << 2)
+#define STAT_TIME_OUT_RESPONSE (1 << 1)
+#define STAT_READ_TIME_OUT (1 << 0)
+
+#define SPI_CS_ADDRESS (1 << 3)
+#define SPI_CS_EN (1 << 2)
+#define CRC_ON (1 << 1)
+#define SPI_EN (1 << 0)
+
+#define CMDAT_SDIO_INT_EN (1 << 11)
+#define CMDAT_STOP_TRAN (1 << 10)
+#define CMDAT_SD_4DAT (1 << 8)
+#define CMDAT_DMAEN (1 << 7)
+#define CMDAT_INIT (1 << 6)
+#define CMDAT_BUSY (1 << 5)
+#define CMDAT_STREAM (1 << 4) /* 1 = stream */
+#define CMDAT_WRITE (1 << 3) /* 1 = write */
+#define CMDAT_DATAEN (1 << 2)
+#define CMDAT_RESP_NONE (0 << 0)
+#define CMDAT_RESP_SHORT (1 << 0)
+#define CMDAT_RESP_R2 (2 << 0)
+#define CMDAT_RESP_R3 (3 << 0)
+
+#define RDTO_MAX 0xffff
+
+#define BUF_PART_FULL (1 << 0)
+
+#define SDIO_SUSPEND_ACK (1 << 12)
+#define SDIO_INT (1 << 11)
+#define RD_STALLED (1 << 10)
+#define RES_ERR (1 << 9)
+#define DAT_ERR (1 << 8)
+#define TINT (1 << 7)
+#define TXFIFO_WR_REQ (1 << 6)
+#define RXFIFO_RD_REQ (1 << 5)
+#define CLK_IS_OFF (1 << 4)
+#define STOP_CMD (1 << 3)
+#define END_CMD_RES (1 << 2)
+#define PRG_DONE (1 << 1)
+#define DATA_TRAN_DONE (1 << 0)
+
+#define MMC_I_MASK_ALL 0x00001fff
+
+#endif /* #ifndef _SLOT_PXA27X_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.c
new file mode 100644
index 0000000..4d71cb6
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.c
@@ -0,0 +1,563 @@
+/*
+ * Linux PXA27x MMC/SD controller driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/kernel-compat.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/delay.h>
+
+#include "slot_pxa27x.h"
+#include "slot_pxa27x_lx.h"
+
+struct pxa_sdio_controller {
+ struct device *dev;
+
+ spinlock_t lock;
+ struct sdio_cmd *current_cmd;
+
+ uint32_t mmc_i_mask;
+
+ int irq;
+ int dma;
+ enum dma_data_direction dma_dir;
+ dma_addr_t dma_addr;
+};
+
+static void pxa_sdio_hw_enable_int(struct pxa_sdio_controller *sdioc, uint32_t ints)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdioc->lock, flags);
+
+ sdioc->mmc_i_mask &= ~ints;
+ MMC_I_MASK = sdioc->mmc_i_mask;
+
+ spin_unlock_irqrestore(&sdioc->lock, flags);
+}
+
+static void pxa_sdio_hw_disable_int(struct pxa_sdio_controller *sdioc, uint32_t ints)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdioc->lock, flags);
+
+ sdioc->mmc_i_mask |= ints;
+ MMC_I_MASK = sdioc->mmc_i_mask;
+
+ spin_unlock_irqrestore(&sdioc->lock, flags);
+}
+
+static void pxa_sdio_hw_start_clock(struct pxa_sdio_controller *sdioc)
+{
+ MMC_STRPCL = START_CLOCK;
+}
+
+
+static void pxa_sdio_hw_stop_clock(struct pxa_sdio_controller *sdioc)
+{
+ unsigned timeout = 10000; /* 10 ms */
+
+ MMC_STRPCL = STOP_CLOCK;
+
+ /* Wait for clock to stop. */
+ do {
+ uint32_t stat = MMC_STAT;
+ if (!(stat & STAT_CLK_EN)) {
+ break;
+ }
+ udelay(1);
+ } while (--timeout);
+
+ if (timeout == 0) {
+ dev_err(sdioc->dev, "unable to stop MMCLK\n");
+ }
+}
+
+static int pxa_sdio_hw_set_clock_rate(struct pxa_sdio_controller *sdioc, int clk)
+{
+ uint32_t clk_rate;
+
+ for (clk_rate = 0; clk_rate <= 6; clk_rate++) {
+ if (clk >= PXA27X_MMC_MMCLK_BASE_FREQ / (1 << clk_rate)) {
+ break;
+ }
+ }
+
+ MMC_CLKRT = clk_rate;
+ pxa_sdio_hw_start_clock(sdioc);
+
+ return PXA27X_MMC_MMCLK_BASE_FREQ / (1 << clk_rate);
+}
+
+static void pxa_sdio_hw_start(struct pxa_sdio_controller *sdioc)
+{
+ MMC_SPI = 0;
+ MMC_RESTO = 64;
+ /*
+ * RDTO * 13128 ns is the maximum time between the end bit of the
+ * response and the start bit of the data. This isn't specified
+ * by the SDIO standard so use the maximum possible (~ 80ms).
+ */
+ MMC_RDTO = RDTO_MAX;
+
+ sdioc->mmc_i_mask = MMC_I_MASK_ALL;
+ MMC_I_MASK = sdioc->mmc_i_mask;
+
+ pxa_set_cken(CKEN12_MMC, 1);
+}
+
+static void pxa_sdio_hw_stop(struct pxa_sdio_controller *sdioc)
+{
+ MMC_I_MASK = MMC_I_MASK_ALL;
+
+ pxa_sdio_hw_stop_clock(sdioc);
+ pxa_set_cken(CKEN12_MMC, 0);
+}
+
+static uint32_t pxa_sdio_hw_response_r1(struct pxa_sdio_controller *sdioc)
+{
+ uint32_t r0, r1, r2;
+ r0 = MMC_RES;
+ r1 = MMC_RES;
+ r2 = MMC_RES;
+ return ((r0 & 0xff) << 24) | (r1 << 8) | (r2 >> 8);
+}
+
+static void pxa_sdio_cmd_complete(struct sdio_slot *slot)
+{
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+ uint32_t stat;
+
+ pxa_sdio_hw_disable_int(sdioc, RES_ERR | DAT_ERR | END_CMD_RES
+ | DATA_TRAN_DONE | PRG_DONE);
+
+ /* Check status for error bits. */
+ stat = MMC_STAT;
+ if (stat & STAT_TIME_OUT_RESPONSE) {
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ } else if (stat & STAT_RES_CRC_ERR) {
+ cmd->status = SDD_CMD_ERR_CMD_CRC;
+ } else if (stat & (STAT_CRC_READ_ERROR | STAT_CRC_WRITE_ERROR)) {
+ cmd->status = SDD_CMD_ERR_DAT_CRC;
+ } else if (stat & STAT_READ_TIME_OUT) {
+ cmd->status = SDD_CMD_ERR_DAT_TIMEOUT;
+ } else {
+ cmd->status = SDD_CMD_OK;
+ }
+
+ /* Read response if it's valid. */
+ if (!(cmd->status & SDD_CMD_ERR_CMD)) {
+ switch (cmd->flags & SDD_CMD_FLAG_RESP_MASK) {
+ case SDD_CMD_FLAG_RESP_NONE:
+ break;
+ case SDD_CMD_FLAG_RESP_R1:
+ case SDD_CMD_FLAG_RESP_R1B:
+ case SDD_CMD_FLAG_RESP_R4:
+ case SDD_CMD_FLAG_RESP_R5:
+ case SDD_CMD_FLAG_RESP_R5B:
+ case SDD_CMD_FLAG_RESP_R6:
+ cmd->sdio.response.r1 = pxa_sdio_hw_response_r1(sdioc);
+ break;
+ default:
+ dev_err(sdioc->dev, "response format not supported\n");
+ }
+ }
+
+ if (cmd->data) {
+ DCSR(sdioc->dma) = 0;
+ dma_unmap_single(NULL, sdioc->dma_addr, cmd->len, sdioc->dma_dir);
+ }
+
+ sdio_cmd_complete(slot, cmd);
+}
+
+irqreturn_t pxa_sdio_int_handler(int irq, void *dev_id)
+{
+ struct sdio_slot *slot = dev_id;
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+ uint32_t i_req;
+
+ i_req = MMC_I_REG & ~sdioc->mmc_i_mask;
+
+ /*
+ * Mask any recieved interrupts as they can only be cleared by
+ * starting a new command.
+ */
+ pxa_sdio_hw_disable_int(sdioc, i_req);
+
+ if (i_req & SDIO_INT) {
+ sdio_interrupt(slot);
+ }
+
+ if (i_req & (RES_ERR | DAT_ERR)) {
+ pxa_sdio_cmd_complete(slot);
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * Command has completed, read the response and notify the SDIO
+ * layer unless we're waiting for a data transfer to complete.
+ */
+ if (i_req & END_CMD_RES) {
+ if (!cmd->data) {
+ pxa_sdio_cmd_complete(slot);
+ } else {
+ if (sdioc->dma_dir == DMA_TO_DEVICE) {
+ /*
+ * When Tx'ing, start the DMA now that the response
+ * has been received (PXA270 Errata 91).
+ *
+ * Then wait for DATA_TRAN_DONE (not PRG_DONE, as
+ * PRG_DONE appears to not be cleared unless the card
+ * is in the busy state -- the PXA270 datasheet is not
+ * clear on when PRG_DONE is cleared).
+ */
+ DCSR(sdioc->dma) = DCSR_NODESC | DCSR_RUN;
+ pxa_sdio_hw_enable_int(sdioc, DATA_TRAN_DONE);
+ } else {
+ /*
+ * When Rx'ing, wait for the DMA complete interrupt to
+ * ensure that both the transfer from the card has
+ * completed and the data is written to memory.
+ */
+ }
+ }
+ }
+
+ if (i_req & DATA_TRAN_DONE) {
+ /*
+ * If an R1b or R5b (busy) response is expected and the card
+ * is still busy, wait for the PRG_DONE interrupt.
+ */
+ if (((cmd->flags & SDD_CMD_FLAG_RESP_MASK) == SDD_CMD_FLAG_RESP_R5B ||
+ (cmd->flags & SDD_CMD_FLAG_RESP_MASK) == SDD_CMD_FLAG_RESP_R1B)
+ && !(MMC_STAT & STAT_PRG_DONE)) {
+ pxa_sdio_hw_enable_int(sdioc, PRG_DONE);
+ } else {
+ pxa_sdio_cmd_complete(slot);
+ }
+ }
+
+ if (i_req & PRG_DONE) {
+ pxa_sdio_cmd_complete(slot);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void pxa_sdio_dma_int_handler(int dma, void *devid, struct pt_regs *regs)
+{
+ struct sdio_slot *slot = devid;
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+
+ DCSR(dma) = DCSR_ENDINTR;
+
+ if (sdioc->dma_dir == DMA_FROM_DEVICE) {
+ pxa_sdio_cmd_complete(slot);
+ } else {
+ /* Swap a partially filled TxD FIFO. */
+ if (sdioc->current_cmd->len % PXA27X_MMC_FIFO_SIZE) {
+ MMC_PRTBUF = BUF_PART_FULL;
+ }
+ }
+}
+
+
+static int pxa_set_bus_freq(struct sdio_slot *slot, unsigned clk)
+{
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+
+ if (clk == SDD_BUS_FREQ_OFF) {
+ pxa_sdio_hw_stop_clock(sdioc);
+ return 0;
+ } else if (clk == SDD_BUS_FREQ_IDLE) {
+ /*
+ * Reduce MMCLK instead of stopping it as the PXA27x MMC
+ * controller requires MMCLK to detect SDIO interrupts.
+ */
+ clk = 400000;
+ }
+ return pxa_sdio_hw_set_clock_rate(sdioc, clk);
+}
+
+static int pxa_sdio_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+ uint32_t nob, blklen, cmdat = CMDAT_SDIO_INT_EN;
+
+ sdioc->current_cmd = cmd;
+
+ /* The first command (which will always be a CMD0) must be
+ * preceeded by at least 64 clocks. */
+ if (cmd->sdio.cmd == 0) {
+ cmdat |= CMDAT_INIT;
+ }
+
+ if (slot->bus_width == 4) {
+ cmdat |= CMDAT_SD_4DAT;
+ }
+
+ switch (cmd->flags & SDD_CMD_FLAG_RESP_MASK) {
+ case SDD_CMD_FLAG_RESP_NONE:
+ cmdat |= CMDAT_RESP_NONE;
+ break;
+ case SDD_CMD_FLAG_RESP_R1B:
+ case SDD_CMD_FLAG_RESP_R5B:
+ cmdat |= CMDAT_BUSY;
+ /* fall through */
+ case SDD_CMD_FLAG_RESP_R1:
+ case SDD_CMD_FLAG_RESP_R5:
+ case SDD_CMD_FLAG_RESP_R6:
+ cmdat |= CMDAT_RESP_SHORT;
+ break;
+ case SDD_CMD_FLAG_RESP_R2:
+ cmdat |= CMDAT_RESP_R2;
+ break;
+ case SDD_CMD_FLAG_RESP_R3:
+ case SDD_CMD_FLAG_RESP_R4:
+ cmdat |= CMDAT_RESP_R3;
+ break;
+ }
+
+ if (cmd->flags & SDD_CMD_FLAG_ABORT) {
+ cmdat |= CMDAT_STOP_TRAN;
+ }
+
+ if (cmd->data) {
+ cmdat |= CMDAT_DMAEN | CMDAT_DATAEN;
+ cmdat |= (cmd->flags & SDD_CMD_FLAG_READ) ? 0 : CMDAT_WRITE;
+
+ if (cmd->len < cmd->owner->blocksize) {
+ blklen = cmd->len;
+ nob = 1;
+ } else {
+ blklen = cmd->owner->blocksize;
+ nob = cmd->len / blklen;
+ }
+
+ sdioc->dma_dir = (cmd->flags & SDD_CMD_FLAG_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ sdioc->dma_addr = dma_map_single(NULL, cmd->data, cmd->len, sdioc->dma_dir);
+
+ DCSR(sdioc->dma) = DCSR_NODESC;
+ if (sdioc->dma_dir == DMA_FROM_DEVICE) {
+ DSADR(sdioc->dma) = __PREG(MMC_RXFIFO);
+ DTADR(sdioc->dma) = sdioc->dma_addr;
+ DCMD(sdioc->dma) = (DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_WIDTH1 |
+ DCMD_BURST32 | DCMD_ENDIRQEN | (cmd->len & DCMD_LENGTH));
+ /* Start the Rx DMA. */
+ DCSR(sdioc->dma) = DCSR_NODESC | DCSR_RUN;
+ } else {
+ DSADR(sdioc->dma) = sdioc->dma_addr;
+ DTADR(sdioc->dma) = __PREG(MMC_TXFIFO);
+ DCMD(sdioc->dma) = (DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_WIDTH1 |
+ DCMD_BURST32 | DCMD_ENDIRQEN | (cmd->len & DCMD_LENGTH));
+ /*
+ * Starting the Tx DMA here before the response has been
+ * received results in incorrect data being Tx'd (PXA270
+ * Errata 91).
+ */
+ }
+ } else {
+ nob = blklen = 0;
+ }
+
+ /* Start the command. */
+ if (blklen) {
+ MMC_BLKLEN = blklen;
+ }
+ if (nob) {
+ MMC_NOB = nob;
+ }
+ MMC_CMD = cmd->sdio.cmd;
+ MMC_ARGH = cmd->sdio.arg >> 16;
+ MMC_ARGL = cmd->sdio.arg & 0xffff;
+ MMC_CMDAT = cmdat;
+
+ pxa_sdio_hw_enable_int(sdioc, RES_ERR | DAT_ERR | END_CMD_RES);
+
+ return 0;
+}
+
+static int pxa_sdio_card_present(struct sdio_slot *slot)
+{
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+ struct pxa27x_sdio_plat_data *pdata = sdioc->dev->platform_data;
+
+ return pdata->card_present(sdioc->dev);
+}
+
+static int pxa_sdio_card_power(struct sdio_slot *slot, enum sdio_power power)
+{
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+ struct pxa27x_sdio_plat_data *pdata = sdioc->dev->platform_data;
+
+ return pdata->card_power(sdioc->dev, power);
+}
+
+static void pxa_sdio_enable_card_int(struct sdio_slot *slot)
+{
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+
+ pxa_sdio_hw_enable_int(sdioc, SDIO_INT);
+}
+
+static void pxa_sdio_disable_card_int(struct sdio_slot *slot)
+{
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+
+ pxa_sdio_hw_disable_int(sdioc, SDIO_INT);
+}
+
+static int pxa_sdio_probe(struct platform_device *dev)
+{
+ struct sdio_slot *slot;
+ struct pxa_sdio_controller *sdioc;
+ int ret;
+
+ slot = sdio_slot_alloc(sizeof(struct pxa_sdio_controller));
+ if (!slot) {
+ return -ENOMEM;
+ }
+ platform_set_drvdata(dev, slot);
+
+ strcpy(slot->name, dev->dev.bus_id);
+ slot->type = SDD_SLOT_TYPE_SD;
+ slot->set_bus_freq = pxa_set_bus_freq;
+ slot->start_cmd = pxa_sdio_start_cmd;
+ slot->card_present = pxa_sdio_card_present;
+ slot->card_power = pxa_sdio_card_power;
+ slot->enable_card_int = pxa_sdio_enable_card_int;
+ slot->disable_card_int = pxa_sdio_disable_card_int;
+
+ slot->caps.max_bus_width = 4;
+
+ sdioc = slot->drv_data;
+
+ sdioc->dev = &dev->dev;
+ spin_lock_init(&sdioc->lock);
+
+ pxa_sdio_hw_start(sdioc);
+
+ sdioc->dma = pxa_request_dma(slot->name, DMA_PRIO_LOW, pxa_sdio_dma_int_handler, slot);
+ if (sdioc->dma < 0) {
+ ret = -EBUSY;
+ goto error;
+ }
+ DCSR(sdioc->dma) = 0;
+ DRCMRRXMMC = (sdioc->dma & DRCMR_CHLNUM) | DRCMR_MAPVLD;
+ DRCMRTXMMC = (sdioc->dma & DRCMR_CHLNUM) | DRCMR_MAPVLD;
+ DALGN |= 1 << sdioc->dma; /* FIXME: this should be set by the kernel. */
+
+ ret = request_irq(IRQ_MMC, pxa_sdio_int_handler, 0, slot->name, slot);
+ if (ret) {
+ goto error;
+ }
+ sdioc->irq = IRQ_MMC;
+
+ ret = sdio_slot_register(slot);
+ if (ret) {
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ pxa_sdio_hw_stop(sdioc);
+ if (sdioc->dma >= 0) {
+ pxa_free_dma(sdioc->dma);
+ }
+ if (sdioc->irq) {
+ free_irq(sdioc->irq, slot);
+ }
+ sdio_slot_free(slot);
+ return ret;
+}
+
+static int pxa_sdio_remove(struct platform_device *dev)
+{
+ struct sdio_slot *slot = platform_get_drvdata(dev);
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+
+ sdio_slot_unregister(slot);
+
+ pxa_sdio_hw_stop(sdioc);
+
+ free_irq(sdioc->irq, slot);
+ pxa_free_dma(sdioc->dma);
+
+ sdio_slot_free(slot);
+
+ return 0;
+}
+
+static int pxa_sdio_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct sdio_slot *slot = platform_get_drvdata(dev);
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+
+ /* Pass the event to the SDIO driver. */
+ sdio_suspend(slot);
+ /* Stop the SDIO clock, etc. */
+ pxa_sdio_hw_stop(sdioc);
+
+ return 0;
+}
+
+static int pxa_sdio_resume(struct platform_device *dev)
+{
+ struct sdio_slot *slot = platform_get_drvdata(dev);
+ struct pxa_sdio_controller *sdioc = slot->drv_data;
+
+ /* Re-initialise the SDIO H/W. */
+ pxa_sdio_hw_start(sdioc);
+
+ DRCMRRXMMC = (sdioc->dma & DRCMR_CHLNUM) | DRCMR_MAPVLD;
+ DRCMRTXMMC = (sdioc->dma & DRCMR_CHLNUM) | DRCMR_MAPVLD;
+ DALGN |= 1 << sdioc->dma; /* FIXME: this should be set by the kernel. */
+
+ /* Pass the event to the SDIO driver. */
+ sdio_resume(slot);
+ return 0;
+}
+
+
+static struct platform_driver pxa27x_sdio_driver = {
+ .probe = pxa_sdio_probe,
+ .remove = pxa_sdio_remove,
+ .suspend= pxa_sdio_suspend,
+ .resume = pxa_sdio_resume,
+ .driver = {
+ .name = "pxa27x-sdio",
+ },
+};
+
+static int __init slot_pxa27x_init(void)
+{
+ return platform_driver_register(&pxa27x_sdio_driver);
+}
+
+static void __exit slot_pxa27x_exit(void)
+{
+ platform_driver_unregister(&pxa27x_sdio_driver);
+}
+
+module_init(slot_pxa27x_init);
+module_exit(slot_pxa27x_exit);
+
+MODULE_DESCRIPTION("PXA27x MMC/SD controller slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.h b/unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.h
new file mode 100644
index 0000000..6251be8
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_pxa27x_lx.h
@@ -0,0 +1,46 @@
+/*
+ * Linux PXA27x slot driver platform data definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_PXA27X_LX_H
+#define _SLOT_PXA27X_LX_H
+
+#include <sdioemb/slot_api.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+
+#define CKEN12_MMC CKEN_MMC
+
+#define MMC_STRPCL __REG(0x41100000) /* Control to start and stop MMC clock */
+#define MMC_STAT __REG(0x41100004) /* MMC Status Register (read only) */
+#define MMC_CLKRT __REG(0x41100008) /* MMC clock rate */
+#define MMC_SPI __REG(0x4110000c) /* SPI mode control bits */
+#define MMC_CMDAT __REG(0x41100010) /* Command/response/data sequence control */
+#define MMC_RESTO __REG(0x41100014) /* Expected response time out */
+#define MMC_RDTO __REG(0x41100018) /* Expected data read time out */
+#define MMC_BLKLEN __REG(0x4110001c) /* Block length of data transaction */
+#define MMC_NOB __REG(0x41100020) /* Number of blocks, for block mode */
+#define MMC_PRTBUF __REG(0x41100024) /* Partial MMC_TXFIFO FIFO written */
+#define MMC_I_MASK __REG(0x41100028) /* Interrupt Mask */
+#define MMC_I_REG __REG(0x4110002c) /* Interrupt Register (read only) */
+#define MMC_CMD __REG(0x41100030) /* Index of current command */
+#define MMC_ARGH __REG(0x41100034) /* MSW part of the current command argument */
+#define MMC_ARGL __REG(0x41100038) /* LSW part of the current command argument */
+#define MMC_RES __REG(0x4110003c) /* Response FIFO (read only) */
+#define MMC_RXFIFO __REG(0x41100040) /* Receive FIFO (read only) */
+#define MMC_TXFIFO __REG(0x41100044) /* Transmit FIFO (write only) */
+
+#endif
+
+
+struct pxa27x_sdio_plat_data {
+ int (*card_power)(struct device *, enum sdio_power);
+ int (*card_present)(struct device *);
+};
+
+#endif /* #ifndef _SLOT_PXA27X_LX_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_sharp_cxx00.c b/unifi_hostsw_linux_147/sdioemb/slot_sharp_cxx00.c
new file mode 100644
index 0000000..385b26b
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_sharp_cxx00.c
@@ -0,0 +1,113 @@
+/*
+ * Sharp Zaurus C1000/3000/3200 SDIO device.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/arch/spitz.h>
+
+#define SCP_CF_POWER SPITZ_SCP_CF_POWER
+#define GPIO_nSD_DETECT SPITZ_GPIO_nSD_DETECT
+
+#include "slot_pxa27x_lx.h"
+
+static int sharp_cxx00_sdio_card_present(struct device *dev)
+{
+ return !(GPLR(GPIO_nSD_DETECT) & GPIO_bit(GPIO_nSD_DETECT));
+}
+
+static int sharp_cxx00_sdio_card_power(struct device *dev, enum sdio_power power)
+{
+ unsigned short cpr;
+
+ if (power != SDIO_POWER_OFF) {
+ set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+
+ cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
+ if( ( cpr & (0x0004| 0x0002) ) == 0 )
+ {
+ msleep_interruptible(5);
+ }
+ cpr |= 0x0004;
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr );
+ }
+ else {
+ cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
+ cpr &= ~(0x004);
+ write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr );
+
+ msleep_interruptible(5);
+
+ if (!(cpr & 0x2))
+ {
+ reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+ }
+ }
+
+ return 0;
+}
+
+static struct pxa27x_sdio_plat_data sharp_cxx00_sdio_plat_data = {
+ .card_present = sharp_cxx00_sdio_card_present,
+ .card_power = sharp_cxx00_sdio_card_power,
+};
+
+static struct platform_device sharp_cxx00_sdio_devices[] = {
+ {
+ .name = "pxa27x-sdio",
+ .id = 0,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &sharp_cxx00_sdio_plat_data,
+ },
+ },
+};
+
+static int __init slot_sharp_cxx00_init(void)
+{
+ int i;
+
+ /* Setup SDIO card detect GPIO */
+ pxa_gpio_mode(GPIO_nSD_DETECT | GPIO_IN); /* inout */
+
+ /*
+ * Make sure GPIOs are configured for SDIO operation.
+ * See PXA27x developers manual pages 24-5/6/7/8
+ * MMC CLK GPIO 32 alternate function 2
+ * MMC DAT0 GPIO 92 alternate function 1
+ * MMC DAT1 GPIO 109 - ditto -
+ * MMC DAT2 GPIO 110 - ditto -
+ * MMC DAT3 GPIO 111 - ditto -
+ * MMC CMD GPIO 112 - ditto -
+ */
+ pxa_gpio_mode(32 | GPIO_ALT_FN_2_OUT);
+ pxa_gpio_mode(92 | GPIO_ALT_FN_1_OUT);
+ pxa_gpio_mode(109 | GPIO_ALT_FN_1_OUT);
+ pxa_gpio_mode(110 | GPIO_ALT_FN_1_OUT);
+ pxa_gpio_mode(111 | GPIO_ALT_FN_1_OUT);
+ pxa_gpio_mode(112 | GPIO_ALT_FN_1_OUT);
+
+ for (i = 0; i < ARRAY_SIZE(sharp_cxx00_sdio_devices); i++) {
+ platform_device_register(&sharp_cxx00_sdio_devices[i]);
+ }
+
+ return 0;
+}
+
+module_init(slot_sharp_cxx00_init);
+
+MODULE_DESCRIPTION("Sharp Zaurus C1000/3000/32000 SDIO slot device");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_shc.h b/unifi_hostsw_linux_147/sdioemb/slot_shc.h
new file mode 100644
index 0000000..87976fa
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_shc.h
@@ -0,0 +1,119 @@
+/*
+ * Standard Host Controller definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_SHC_H
+#define _SLOT_SHC_H
+
+/* SHC registers */
+#define SHC_SYSTEM_ADDRESS 0x00
+
+#define SHC_BLOCK_SIZE 0x04
+# define SHC_BLOCK_SIZE_DMA_BOUNDRY_4K 0x0000
+
+#define SHC_BLOCK_COUNT 0x06
+#define SHC_ARG 0x08
+
+#define SHC_TRANSFER_MODE 0x0c
+# define SHC_TRANSFER_MODE_DMA_EN 0x0001
+# define SHC_TRANSFER_MODE_BLK_CNT_EN 0x0002
+# define SHC_TRANSFER_MODE_AUTO_CMD12_EN 0x0004
+# define SHC_TRANSFER_MODE_DATA_READ 0x0010
+# define SHC_TRANSFER_MODE_MULTI_BLK 0x0020
+
+#define SHC_CMD 0x0e
+# define SHC_CMD_RESP_NONE 0x0000
+# define SHC_CMD_RESP_136 0x0001
+# define SHC_CMD_RESP_48 0x0002
+# define SHC_CMD_RESP_48B 0x0003
+# define SHC_CMD_RESP_CRC_CHK 0x0008
+# define SHC_CMD_RESP_IDX_CHK 0x0010
+# define SHC_CMD_DATA_PRESENT 0x0020
+# define SHC_CMD_TYPE_ABORT (0x3 << 6)
+# define SHC_CMD_IDX(c) ((c) << 8)
+
+#define SHC_RESPONSE_0_31 0x10
+
+#define SHC_BUFFER_DATA_PORT 0x20
+
+#define SHC_PRESENT_STATE 0x24
+# define SHC_PRESENT_STATE_CMD_INHIBIT 0x00000001
+# define SHC_PRESENT_STATE_DAT_INHIBIT 0x00000002
+# define SHC_PRESENT_STATE_CARD_PRESENT 0x00010000
+
+#define SHC_HOST_CTRL 0x28
+# define SHC_HOST_CTRL_LED_ON 0x01
+# define SHC_HOST_CTRL_4BIT 0x02
+# define SHC_HOST_CTRL_HIGH_SPD_EN 0x04
+
+
+#define SHC_PWR_CTRL 0x29
+# define SHC_PWR_CTRL_3V3 0x0e
+# define SHC_PWR_CTRL_ON 0x01
+
+#define SHC_BLOCK_GAP_CTRL 0x2a
+#define SHC_WAKEUP_CTRL 0x2b
+
+#define SHC_CLOCK_CTRL 0x2c
+# define SHC_CLOCK_CTRL_INT_CLK_EN 0x01
+# define SHC_CLOCK_CTRL_INT_CLK_STABLE 0x02
+# define SHC_CLOCK_CTRL_SD_CLK_EN 0x04
+# define SHC_CLOCK_CTRL_DIV(d) (((d) >> 1) << 8) /* divisor must be power of 2 */
+
+#define SHC_TIMEOUT_CTRL 0x2e
+# define SHC_TIMEOUT_CTRL_MAX 0x0e
+
+#define SHC_SOFTWARE_RST 0x2f
+# define SHC_SOFTWARE_RST_ALL 0x01
+# define SHC_SOFTWARE_RST_CMD 0x02
+# define SHC_SOFTWARE_RST_DAT 0x04
+
+#define SHC_INT_STATUS 0x30
+#define SHC_INT_STATUS_EN 0x34
+#define SHC_INT_SIGNAL_EN 0x38
+# define SHC_INT_CMD_COMPLETE 0x00000001
+# define SHC_INT_TRANSFER_COMPLETE 0x00000002
+# define SHC_INT_BLOCK_GAP 0x00000004
+# define SHC_INT_DMA 0x00000008
+# define SHC_INT_WR_BUF_RDY 0x00000010
+# define SHC_INT_RD_BUF_RDY 0x00000020
+# define SHC_INT_CARD_INSERTED 0x00000040
+# define SHC_INT_CARD_REMOVED 0x00000080
+# define SHC_INT_CARD_INT 0x00000100
+# define SHC_INT_ERR_ANY 0x00008000
+# define SHC_INT_ERR_CMD_TIMEOUT 0x00010000
+# define SHC_INT_ERR_CMD_CRC 0x00020000
+# define SHC_INT_ERR_CMD_ENDBIT 0x00040000
+# define SHC_INT_ERR_CMD_INDEX 0x00080000
+# define SHC_INT_ERR_CMD_ALL 0x000f0000
+# define SHC_INT_ERR_DAT_TIMEOUT 0x00100000
+# define SHC_INT_ERR_DAT_CRC 0x00200000
+# define SHC_INT_ERR_DAT_ENDBIT 0x00400000
+# define SHC_INT_ERR_DAT_ALL 0x00700000
+# define SHC_INT_ERR_CURRENT_LIMIT 0x00800000
+# define SHC_INT_ERR_AUTO_CMD12 0x01000000
+# define SHC_INT_ERR_ALL 0x01ff0000
+# define SHC_INT_ALL 0x01ff81ff
+
+#define SHC_AUTO_CMD12_STATUS 0x3c
+
+#define SHC_CAPS 0x40
+# define SHC_CAPS_TO_BASE_CLK_FREQ(c) (((c) & 0x00003f00) >> 8)
+# define SHC_CAPS_PWR_3V3 (1 << 24)
+
+#define SHC_MAX_CURRENT_CAPS 0x4c
+
+/* PCI configuration registers. */
+#define PCI_SHC_SLOT_INFO 0x40
+
+/* Maximum time to wait for a software reset. */
+#define SHC_RESET_TIMEOUT_MS 100 /* ms */
+
+/* Maximum time to wait for internal clock to stabilize */
+#define SHC_INT_CLK_STABLE_TIMEOUT_MS 100
+
+#endif /* #ifndef _SLOT_SHC_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_shc_pci_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_shc_pci_lx.c
new file mode 100644
index 0000000..bf2eac9
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_shc_pci_lx.c
@@ -0,0 +1,904 @@
+/*
+ * Linux PCI SHC slot driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * References:
+ * [SDHC] SD Host Controller Standard Specification v1.00.
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>
+#include <linux/kernel-compat.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+
+#include <sdioemb/sdio_api.h>
+#include <sdioemb/slot_api.h>
+
+#include "sdio_layer.h"
+#include "slot_shc.h"
+
+struct shc_data {
+ struct pci_dev *pdev;
+ void __iomem *addr;
+ spinlock_t lock;
+ struct timer_list lockup_timer;
+ unsigned long quirks;
+ unsigned base_clk;
+ struct sdio_cmd *current_cmd;
+ dma_addr_t dma_addr;
+ uint8_t *data;
+ size_t remaining;
+ size_t block_size;
+};
+
+/*
+ * No supported voltages in the capabilities register.
+ *
+ * Workaround: Assume 3.3V is supported.
+ */
+#define SLOT_SHC_QUIRK_NO_VOLTAGE_CAPS (1 << 0)
+
+/*
+ * Commands with an R5B (busy) response do not complete.
+ *
+ * Workaround: Use R5 instead. This will only work if the busy signal
+ * is cleared sufficiently quickly before the next command is started.
+ */
+#define SLOT_SHC_QUIRK_R5B_BROKEN (1 << 1)
+
+/*
+ * High speed mode doesn't work.
+ *
+ * Workaround: limit maximum bus frequency to 25 MHz.
+ */
+#define SLOT_SHC_QUIRK_HIGH_SPD_BROKEN (1 << 2)
+
+/*
+ * Data timeout (TIMEOUT_CTRL) uses SDCLK and not TMCLK.
+ *
+ * Workaround: set TIMEOUT_CTRL using SDCLK.
+ */
+#define SLOT_SHC_QUIRK_DATA_TIMEOUT_USES_SDCLK (1 << 3)
+
+/*
+ * Controller can only start and end DMA on dword (32 bit) aligned
+ * addresses.
+ *
+ * Workaround: PIO is used on data transfers with a non-dword aligned
+ * address or length.
+ */
+#define SHC_QUIRK_DMA_DWORD_ALIGNED_ONLY (1 << 4)
+
+/* Software timeout for commands. For working around buggy controllers
+ that occasionally fail to complete a command. */
+#define SLOT_SHC_LOCKUP_TIMEOUT_MS 2000
+
+static int shc_hw_reset(struct shc_data *shc, uint8_t rst_bits)
+{
+ int timeout = SHC_RESET_TIMEOUT_MS;
+
+ writeb(rst_bits, shc->addr + SHC_SOFTWARE_RST);
+ while (--timeout) {
+ if (!(readb(shc->addr + SHC_SOFTWARE_RST) & rst_bits)) {
+ break;
+ }
+ /* Must be mdelay not msleep, as called from interrupt context */
+ mdelay(1);
+ }
+ if (!timeout) {
+ dev_err(&shc->pdev->dev, "timed out waiting for reset\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int shc_hw_init(struct shc_data *shc)
+{
+ uint32_t caps;
+ int ret;
+ int timeout;
+
+ ret = shc_hw_reset(shc, SHC_SOFTWARE_RST_ALL);
+ if (ret) {
+ return ret;
+ }
+
+ /* read and check various capabilties */
+ caps = readl(shc->addr + SHC_CAPS);
+
+ shc->base_clk = 1000000 * SHC_CAPS_TO_BASE_CLK_FREQ(caps);
+ if (shc->base_clk == 0) {
+ dev_err(&shc->pdev->dev, "cannot determine base SD clock frequency\n");
+ return -EIO;
+ }
+
+ /* mask all interrupts */
+ writel(0, shc->addr + SHC_INT_STATUS_EN);
+
+ /* allow any unmasked interrupt to raise an interrupt */
+ writel(SHC_INT_ALL, shc->addr + SHC_INT_SIGNAL_EN);
+
+ /* enable internal clock, disable SD clock, and wait for internal
+ * clock to stabilize */
+ writew(SHC_CLOCK_CTRL_INT_CLK_EN, shc->addr + SHC_CLOCK_CTRL);
+ timeout = SHC_INT_CLK_STABLE_TIMEOUT_MS;
+ while (--timeout) {
+ if (readw(shc->addr + SHC_CLOCK_CTRL) & SHC_CLOCK_CTRL_INT_CLK_STABLE) {
+ break;
+ }
+ msleep(1);
+ }
+ if (!timeout) {
+ dev_err(&shc->pdev->dev, "timed out waiting for internal clock to stabilize\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static void shc_hw_stop(struct shc_data *shc)
+{
+ writew(0, shc->addr + SHC_CLOCK_CTRL);
+}
+
+static void shc_hw_set_high_speed(struct shc_data *shc, int hs)
+{
+ unsigned long flags;
+ u8 host_ctrl;
+
+ spin_lock_irqsave(&shc->lock, flags);
+
+ host_ctrl = readb(shc->addr + SHC_HOST_CTRL) & ~SHC_HOST_CTRL_HIGH_SPD_EN;
+ if (hs) {
+ host_ctrl |= SHC_HOST_CTRL_HIGH_SPD_EN;
+ }
+ writeb(host_ctrl, shc->addr + SHC_HOST_CTRL);
+
+ spin_unlock_irqrestore(&shc->lock, flags);
+}
+
+static int shc_hw_set_clock_rate(struct shc_data *shc, int clk)
+{
+ uint16_t clk_reg;
+
+ /* Stop the clock before changing the frequency. */
+ clk_reg = readw(shc->addr + SHC_CLOCK_CTRL);
+ clk_reg &= ~SHC_CLOCK_CTRL_SD_CLK_EN;
+ writew(clk_reg, shc->addr + SHC_CLOCK_CTRL);
+
+ shc_hw_set_high_speed(shc, clk > SDIO_CLOCK_FREQ_NORMAL_SPD);
+
+ if (clk) {
+ int divisor;
+ unsigned long timeout_clks;
+ uint8_t timeout_ctrl;
+
+ /* Find maximum possible bus freq <= clk (or the minimum the
+ controller is capable of)... */
+ for (divisor = 1; divisor < 256; divisor *= 2) {
+ if (shc->base_clk / divisor <= clk) {
+ break;
+ }
+ }
+ clk = shc->base_clk / divisor;
+
+ /* ...and start it. */
+ clk_reg = SHC_CLOCK_CTRL_DIV(divisor) | SHC_CLOCK_CTRL_INT_CLK_EN;
+ writew(clk_reg, shc->addr + SHC_CLOCK_CTRL);
+ clk_reg |= SHC_CLOCK_CTRL_SD_CLK_EN;
+ writew(clk_reg, shc->addr + SHC_CLOCK_CTRL);
+
+ /*
+ * Set the data timeout to 1 s.
+ */
+ if (shc->quirks & SLOT_SHC_QUIRK_DATA_TIMEOUT_USES_SDCLK) {
+ timeout_clks = clk;
+ } else {
+ timeout_clks = shc->base_clk;
+ }
+ for (timeout_ctrl = 0; timeout_ctrl < SHC_TIMEOUT_CTRL_MAX; timeout_ctrl++) {
+ if ((1 << (timeout_ctrl + 13)) >= timeout_clks) {
+ break;
+ }
+ }
+ writeb(timeout_ctrl, shc->addr + SHC_TIMEOUT_CTRL);
+ }
+
+ return clk;
+}
+
+static void shc_hw_set_bus_width(struct shc_data *shc, int bus_width)
+{
+ unsigned long flags;
+ u8 host_ctrl;
+
+ spin_lock_irqsave(&shc->lock, flags);
+
+ host_ctrl = readb(shc->addr + SHC_HOST_CTRL);
+ if (bus_width == 4) {
+ host_ctrl |= SHC_HOST_CTRL_4BIT;
+ } else {
+ host_ctrl &= ~SHC_HOST_CTRL_4BIT;
+ }
+ writeb(host_ctrl, shc->addr + SHC_HOST_CTRL);
+
+ spin_unlock_irqrestore(&shc->lock, flags);
+}
+
+/*
+ * Interrupts are masked/unmasked using INT_STATUS_EN (not
+ * INT_SIGNAL_EN) as this is what the card interrupt requires.
+ */
+static void shc_hw_enable_int_signal(struct shc_data *shc, uint32_t sigs)
+{
+ unsigned long flags;
+ uint32_t stat_en;
+
+ spin_lock_irqsave(&shc->lock, flags);
+
+ stat_en = readl(shc->addr + SHC_INT_STATUS_EN);
+ writel(stat_en | sigs, shc->addr + SHC_INT_STATUS_EN);
+
+ (void)readl(shc->addr + SHC_INT_STATUS_EN); /* flush posted writes */
+ spin_unlock_irqrestore(&shc->lock, flags);
+}
+
+static void shc_hw_disable_int_signal(struct shc_data *shc, uint32_t sigs)
+{
+ unsigned long flags;
+ uint32_t stat_en;
+
+ spin_lock_irqsave(&shc->lock, flags);
+
+ stat_en = readl(shc->addr + SHC_INT_STATUS_EN);
+ writel(stat_en & ~sigs, shc->addr + SHC_INT_STATUS_EN);
+
+ (void)readl(shc->addr + SHC_INT_STATUS_EN); /* flush posted writes */
+ spin_unlock_irqrestore(&shc->lock, flags);
+}
+
+static void shc_hw_read_block_pio(struct shc_data *shc)
+{
+ size_t len;
+ uint32_t dword;
+ int bytes = 0;
+ size_t i;
+
+ len = min(shc->block_size, shc->remaining);
+
+ for (i = 0; i < len; i++) {
+ if (bytes == 0) {
+ dword = readl(shc->addr + SHC_BUFFER_DATA_PORT);
+ bytes = 4;
+ }
+
+ *(shc->data++) = dword & 0xff;
+ dword >>= 8;
+ shc->remaining--;
+ bytes--;
+ }
+}
+
+static void shc_hw_write_block_pio(struct shc_data *shc)
+{
+ size_t len;
+ uint32_t dword = 0;
+ int bytes = 0;
+ size_t i;
+
+ len = min(shc->block_size, shc->remaining);
+
+ for (i = 0; i < len; i++) {
+ dword |= ((uint32_t)*(shc->data++)) << (bytes * 8);
+ shc->remaining--;
+ bytes++;
+
+ if (bytes == 4 || shc->remaining == 0) {
+ writel(dword, shc->addr + SHC_BUFFER_DATA_PORT);
+ dword = 0;
+ bytes = 0;
+ }
+ }
+}
+
+static void shc_hw_setup_data_pio(struct shc_data *shc)
+{
+ struct sdio_cmd *cmd = shc->current_cmd;
+
+ shc->dma_addr = 0;
+ shc->data = cmd->data;
+ shc->remaining = cmd->len;
+ shc->block_size = cmd->owner->blocksize;
+
+ if (cmd->flags & SDD_CMD_FLAG_READ) {
+ shc_hw_enable_int_signal(shc, SHC_INT_RD_BUF_RDY);
+ } else {
+ shc_hw_enable_int_signal(shc, SHC_INT_WR_BUF_RDY);
+ }
+}
+
+static int int_stat_to_status(uint32_t int_stat)
+{
+ int status;
+
+ if (int_stat & (SHC_INT_ERR_CMD_ALL | SHC_INT_ERR_DAT_ALL)) {
+ if (int_stat & SHC_INT_ERR_CMD_ALL) {
+ status = SDD_CMD_ERR_CMD;
+ } else {
+ status = SDD_CMD_ERR_DAT;
+ }
+ if (int_stat & (SHC_INT_ERR_CMD_TIMEOUT | SHC_INT_ERR_DAT_TIMEOUT)) {
+ status |= SDD_CMD_ERR_TIMEOUT;
+ } else {
+ status |= SDD_CMD_ERR_CRC;
+ }
+ } else {
+ status = SDD_CMD_OK;
+ }
+ return status;
+}
+
+static void shc_cmd_complete(struct sdio_slot *slot, int status)
+{
+ struct shc_data *shc = slot->drv_data;
+ struct sdio_cmd *cmd = shc->current_cmd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&shc->lock, flags);
+ cmd = shc->current_cmd;
+ shc->current_cmd = NULL;
+ spin_unlock_irqrestore(&shc->lock, flags);
+
+ if (cmd == NULL) {
+ dev_err(&shc->pdev->dev, "spurious command complete interrupt\n");
+ return;
+ }
+
+ cmd->status = status;
+
+ /* disable transfer related interrupts */
+ shc_hw_disable_int_signal(shc, SHC_INT_ERR_ALL | SHC_INT_CMD_COMPLETE
+ | SHC_INT_TRANSFER_COMPLETE
+ | SHC_INT_RD_BUF_RDY | SHC_INT_WR_BUF_RDY);
+
+ del_timer(&shc->lockup_timer);
+
+ /* Read response if it's valid. */
+ if (!(cmd->status & SDD_CMD_ERR_CMD)) {
+ switch (cmd->flags & SDD_CMD_FLAG_RESP_MASK) {
+ case SDD_CMD_FLAG_RESP_NONE:
+ break;
+ case SDD_CMD_FLAG_RESP_R1:
+ case SDD_CMD_FLAG_RESP_R1B:
+ case SDD_CMD_FLAG_RESP_R4:
+ case SDD_CMD_FLAG_RESP_R5:
+ case SDD_CMD_FLAG_RESP_R5B:
+ case SDD_CMD_FLAG_RESP_R6:
+ cmd->sdio.response.r1 = readl(shc->addr + SHC_RESPONSE_0_31);
+ break;
+ default:
+ dev_err(&shc->pdev->dev, "response format not supported\n");
+ }
+ }
+
+ if (cmd->data) {
+ pci_unmap_single(shc->pdev, shc->dma_addr, cmd->len,
+ (cmd->flags & SDD_CMD_FLAG_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+
+ /*
+ * After an error or abort, reset the DAT and CMD line state
+ * machines. See [SDHC] section 3.7.
+ */
+ if (cmd->status != SDD_CMD_OK || (cmd->flags & SDD_CMD_FLAG_ABORT)) {
+ /* Some controllers do not like having both blocks reset at the same time */
+ shc_hw_reset(shc, SHC_SOFTWARE_RST_CMD);
+ shc_hw_reset(shc, SHC_SOFTWARE_RST_DAT);
+ }
+
+ sdio_cmd_complete(slot, cmd);
+}
+
+static void shc_lockup_timer_fn(unsigned long data)
+{
+ struct sdio_slot *slot = (struct sdio_slot *)data;
+ struct shc_data *shc = slot->drv_data;
+ uint32_t int_stat;
+ int status;
+
+ int_stat = readl(shc->addr + SHC_INT_STATUS);
+ status = int_stat_to_status(int_stat);
+ if (status == SDD_CMD_OK) {
+ if (int_stat & SHC_INT_CMD_COMPLETE) {
+ status = SDD_CMD_ERR_DAT_OTHER;
+ } else {
+ status = SDD_CMD_ERR_CMD_OTHER;
+ }
+ }
+ shc_cmd_complete(slot, status);
+}
+
+static irqreturn_t shc_int_handler(int irq, void *dev_id)
+{
+ struct sdio_slot *slot = dev_id;
+ struct shc_data *shc = slot->drv_data;
+ uint32_t int_stat;
+
+ int_stat = readl(shc->addr + SHC_INT_STATUS);
+ if (int_stat == 0) {
+ return IRQ_NONE;
+ }
+ /* Clear interrupt status. */
+ writel(int_stat, shc->addr + SHC_INT_STATUS);
+
+ if (int_stat & SHC_INT_RD_BUF_RDY) {
+ shc_hw_read_block_pio(shc);
+ }
+ if (int_stat & SHC_INT_WR_BUF_RDY) {
+ shc_hw_write_block_pio(shc);
+ }
+
+ if (int_stat & (SHC_INT_ERR_ALL | SHC_INT_CMD_COMPLETE | SHC_INT_TRANSFER_COMPLETE)) {
+ shc_cmd_complete(slot, int_stat_to_status(int_stat));
+ }
+
+ if (int_stat & SHC_INT_CARD_INT) {
+ sdio_interrupt(slot);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int shc_set_bus_freq(struct sdio_slot *slot, int clk)
+{
+ struct shc_data *shc = slot->drv_data;
+
+ if (clk == SDD_BUS_FREQ_IDLE) {
+ clk = 0;
+ }
+ return shc_hw_set_clock_rate(shc, clk);
+}
+
+static int shc_set_bus_width(struct sdio_slot *slot, int bus_width)
+{
+ struct shc_data *shc = slot->drv_data;
+
+ shc_hw_set_bus_width(shc, bus_width);
+ return 0;
+}
+
+static int shc_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct shc_data *shc = slot->drv_data;
+ uint32_t system_addr;
+ uint16_t block_size, block_count;
+ uint16_t transfer_mode, command;
+
+ static const uint16_t resp_map[] = {
+ [SDD_CMD_FLAG_RESP_NONE] = 0,
+ [SDD_CMD_FLAG_RESP_R1] = SHC_CMD_RESP_48 | SHC_CMD_RESP_IDX_CHK | SHC_CMD_RESP_CRC_CHK,
+ [SDD_CMD_FLAG_RESP_R1B] = SHC_CMD_RESP_48B | SHC_CMD_RESP_IDX_CHK | SHC_CMD_RESP_CRC_CHK,
+ [SDD_CMD_FLAG_RESP_R2] = SHC_CMD_RESP_136 | SHC_CMD_RESP_CRC_CHK,
+ [SDD_CMD_FLAG_RESP_R3] = SHC_CMD_RESP_48,
+ [SDD_CMD_FLAG_RESP_R4] = SHC_CMD_RESP_48,
+ [SDD_CMD_FLAG_RESP_R5] = SHC_CMD_RESP_48 | SHC_CMD_RESP_IDX_CHK | SHC_CMD_RESP_CRC_CHK,
+ [SDD_CMD_FLAG_RESP_R5B] = SHC_CMD_RESP_48B | SHC_CMD_RESP_IDX_CHK | SHC_CMD_RESP_CRC_CHK,
+ [SDD_CMD_FLAG_RESP_R6] = SHC_CMD_RESP_48 | SHC_CMD_RESP_IDX_CHK | SHC_CMD_RESP_CRC_CHK,
+ };
+
+ shc->current_cmd = cmd;
+
+ /* The first command (which will always be a CMD0) must be
+ * preceeded by at least 64 clocks. */
+ if (cmd->sdio.cmd == 0) {
+ udelay(64 * 1000000 / slot->clock_freq + 1);
+ }
+
+ /* enable command complete, error, data transfer
+ * etc. interrupts */
+ shc_hw_enable_int_signal(shc, SHC_INT_ERR_CMD_ALL | SHC_INT_ERR_DAT_ALL
+ | (cmd->data ? SHC_INT_TRANSFER_COMPLETE : SHC_INT_CMD_COMPLETE));
+
+ /* Set up data for DMA, poke registers to start cmd */
+ transfer_mode = 0;
+ if (cmd->data) {
+ bool use_pio = shc->quirks & SHC_QUIRK_DMA_DWORD_ALIGNED_ONLY
+ && ((unsigned long)cmd->data & 0x3 || cmd->len & 0x3);
+
+ if (use_pio) {
+ shc_hw_setup_data_pio(shc);
+ } else {
+ shc->dma_addr = pci_map_single(shc->pdev, cmd->data, cmd->len,
+ (cmd->flags & SDD_CMD_FLAG_READ) ? DMA_FROM_DEVICE
+ : DMA_TO_DEVICE);
+ transfer_mode |= SHC_TRANSFER_MODE_DMA_EN;
+ }
+ if (cmd->len < cmd->owner->blocksize) {
+ block_size = cmd->len;
+ block_count = 1;
+ } else {
+ block_size = cmd->owner->blocksize;
+ block_count = cmd->len / block_size;
+ }
+ system_addr = shc->dma_addr;
+ } else {
+ block_size = block_count = system_addr = 0;
+ }
+
+ if (cmd->flags & SDD_CMD_FLAG_READ) {
+ transfer_mode |= SHC_TRANSFER_MODE_DATA_READ;
+ }
+ if (block_count > 0) {
+ transfer_mode |= SHC_TRANSFER_MODE_MULTI_BLK | SHC_TRANSFER_MODE_BLK_CNT_EN;
+ }
+
+ command = SHC_CMD_IDX(cmd->sdio.cmd) | resp_map[cmd->flags & SDD_CMD_FLAG_RESP_MASK];
+ if (cmd->data) {
+ command |= SHC_CMD_DATA_PRESENT;
+ if (shc->quirks & SLOT_SHC_QUIRK_R5B_BROKEN) {
+ /* Swap R5B for R5 */
+ if ((command & SHC_CMD_RESP_48B) == SHC_CMD_RESP_48B) {
+ command &= ~(SHC_CMD_RESP_48B);
+ command |= SHC_CMD_RESP_48;
+ }
+ }
+ }
+ if (cmd->flags & SDD_CMD_FLAG_ABORT) {
+ command |= SHC_CMD_TYPE_ABORT;
+ }
+
+ if (system_addr)
+ writel(system_addr, shc->addr + SHC_SYSTEM_ADDRESS);
+ if (block_count > 0)
+ writew(block_size, shc->addr + SHC_BLOCK_SIZE);
+ if (block_count > 0)
+ writew(block_count, shc->addr + SHC_BLOCK_COUNT);
+ writel(cmd->sdio.arg, shc->addr + SHC_ARG);
+ writew(transfer_mode, shc->addr + SHC_TRANSFER_MODE);
+
+ mod_timer(&shc->lockup_timer, jiffies + msecs_to_jiffies(SLOT_SHC_LOCKUP_TIMEOUT_MS));
+
+ (void)readl(shc->addr); /* flush posted writes */
+ writew(command, shc->addr + SHC_CMD);
+
+ return 0;
+}
+
+static int shc_card_present(struct sdio_slot *slot)
+{
+ struct shc_data *shc = slot->drv_data;
+ uint32_t state;
+
+ /* read card present register */
+ state = readl(shc->addr + SHC_PRESENT_STATE);
+
+ return state & SHC_PRESENT_STATE_CARD_PRESENT;
+}
+
+static int shc_card_power(struct sdio_slot *slot, enum sdio_power power)
+{
+ struct shc_data *shc = slot->drv_data;
+ uint32_t caps;
+ uint8_t pwr_ctrl;
+
+ caps = readl(shc->addr + SHC_CAPS);
+
+ if( shc->quirks & SLOT_SHC_QUIRK_NO_VOLTAGE_CAPS )
+ {
+ /* Add in 3.3V to capabilites - the hardware supports this, but doesn't say! */
+ caps |= SHC_CAPS_PWR_3V3;
+ }
+
+ switch (power) {
+ case SDIO_POWER_OFF:
+ pwr_ctrl = 0;
+ break;
+ case SDIO_POWER_3V3:
+ if (caps & SHC_CAPS_PWR_3V3) {
+ pwr_ctrl = SHC_PWR_CTRL_3V3;
+ writeb(pwr_ctrl, shc->addr + SHC_PWR_CTRL);
+ pwr_ctrl |= SHC_PWR_CTRL_ON;
+ } else {
+ return -ENOTSUPP;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writeb(pwr_ctrl, shc->addr + SHC_PWR_CTRL);
+
+ return 0;
+}
+
+static void shc_enable_card_int(struct sdio_slot *slot)
+{
+ struct shc_data *shc = slot->drv_data;
+
+ shc_hw_enable_int_signal(shc, SHC_INT_CARD_INT);
+}
+
+static void shc_disable_card_int(struct sdio_slot *slot)
+{
+ struct shc_data *shc = slot->drv_data;
+
+ shc_hw_disable_int_signal(shc, SHC_INT_CARD_INT);
+}
+
+
+static int shc_hard_reset(struct sdio_slot *slot)
+{
+ struct shc_data *shc = slot->drv_data;
+ struct sdio_slot_priv *slotp = slot->priv;
+ uint8_t pwr_ctrl;
+
+ shc_hw_set_clock_rate(shc, SDD_BUS_FREQ_OFF);
+
+ /* Power cycle the card. */
+ pwr_ctrl = readb(shc->addr + SHC_PWR_CTRL);
+ writeb(0, shc->addr + SHC_PWR_CTRL);
+ msleep(100); /* short delay to allow voltage to drop */
+ writeb(pwr_ctrl, shc->addr + SHC_PWR_CTRL);
+
+ shc_hw_set_clock_rate(shc, slotp->current_clock_freq);
+
+ return 0;
+}
+
+static struct sdio_slot *shc_pci_slot_init(struct pci_dev *pci, int slot_num, unsigned long quirks)
+{
+ struct sdio_slot *slot;
+ struct shc_data *shc;
+ int ret;
+
+ slot = sdio_slot_alloc(sizeof(struct shc_data));
+ if (!slot) {
+ goto err_alloc;
+ }
+ shc = slot->drv_data;
+
+ shc->pdev = pci;
+ shc->addr = pci_iomap(pci, slot_num, pci_resource_len(pci, slot_num));
+ if (!shc->addr) {
+ goto err_iomap;
+ }
+ shc->quirks = quirks;
+
+ printk("Registered slot %s/%d caps %08x quirks %lx\n", pci->dev.bus_id, slot_num,
+ readl(shc->addr + SHC_CAPS), quirks);
+
+ if (shc_hw_init(shc) != 0) {
+ goto err_init;
+ }
+
+ sprintf(slot->name, "%s-%d", pci->dev.bus_id, slot_num);
+ slot->set_bus_freq = shc_set_bus_freq;
+ slot->set_bus_width = shc_set_bus_width;
+ slot->start_cmd = shc_start_cmd;
+ slot->card_present = shc_card_present;
+ slot->card_power = shc_card_power;
+ slot->enable_card_int = shc_enable_card_int;
+ slot->disable_card_int = shc_disable_card_int;
+ slot->hard_reset = shc_hard_reset;
+
+ slot->caps.max_bus_freq = shc->base_clk;
+ slot->caps.max_bus_width = 4;
+ if (shc->quirks & SLOT_SHC_QUIRK_HIGH_SPD_BROKEN
+ && slot->caps.max_bus_freq > SDIO_CLOCK_FREQ_NORMAL_SPD) {
+ slot->caps.max_bus_freq = SDIO_CLOCK_FREQ_NORMAL_SPD;
+ }
+
+ spin_lock_init(&shc->lock);
+ init_timer (&shc->lockup_timer);
+ shc->lockup_timer.data = (unsigned long)slot;
+ shc->lockup_timer.function = shc_lockup_timer_fn;
+
+ ret = request_irq(pci->irq, shc_int_handler, IRQF_SHARED, "slot_shc", slot);
+ if (ret) {
+ goto err_irq;
+ }
+
+ ret = sdio_slot_register(slot);
+ if (ret) {
+ goto err_register;
+ }
+
+ return slot;
+
+ err_register:
+ free_irq(pci->irq, slot);
+ err_irq:
+ err_init:
+ pci_iounmap(pci, shc->addr);
+ err_iomap:
+ sdio_slot_free(slot);
+ err_alloc:
+ return NULL;
+}
+
+static void shc_pci_slot_cleanup(struct sdio_slot *slot)
+{
+ struct shc_data *shc = slot->drv_data;
+ struct pci_dev *pci = shc->pdev;
+
+ sdio_slot_unregister(slot);
+ shc_hw_stop(shc);
+ free_irq(pci->irq, slot);
+ pci_iounmap(pci, shc->addr);
+ sdio_slot_free(slot);
+}
+
+static int shc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+{
+ int ret;
+ uint8_t num_slots, s;
+ struct sdio_slot **slots;
+ unsigned long quirks;
+
+ ret = pci_enable_device(pci);
+ if (ret)
+ goto err_enable;
+
+ ret = pci_set_dma_mask(pci, DMA_32BIT_MASK);
+ if (ret) {
+ goto err_set_dma_mask;
+ }
+ pci_set_master(pci);
+
+ pci_read_config_byte(pci, PCI_SHC_SLOT_INFO, &num_slots);
+ num_slots = ((num_slots >> 4) & 0x07) + 1;
+
+ slots = kzalloc(sizeof(struct sdio_driver_slot *) * (num_slots + 1), GFP_KERNEL);
+ if (!slots) {
+ ret = -ENOMEM;
+ goto err_no_slots_mem;
+ }
+
+ quirks = id->driver_data;
+
+ pci_set_drvdata(pci, slots);
+
+ for (s = 0; s < num_slots; s++) {
+ struct sdio_slot *slot;
+
+ slot = shc_pci_slot_init(pci, s, quirks);
+ if (!slot) {
+ goto err_init;
+ }
+ slots[s] = slot;
+ }
+
+ return 0;
+
+ err_init:
+ for (s = 0; s < num_slots; s++) {
+ if (slots[s]) {
+ shc_pci_slot_cleanup(slots[s]);
+ }
+ }
+ kfree(slots);
+ pci_set_drvdata(pci, NULL);
+ err_set_dma_mask:
+ err_no_slots_mem:
+ pci_disable_device(pci);
+ err_enable:
+
+ return ret;
+}
+
+static void shc_pci_remove(struct pci_dev *pci)
+{
+ struct sdio_slot **slots = pci_get_drvdata(pci);
+ struct sdio_slot **s;
+
+ if (slots) {
+ s = slots;
+ while (*s) {
+ shc_pci_slot_cleanup(*s);
+ s++;
+ }
+
+ kfree(slots);
+ }
+}
+
+static int shc_pci_suspend(struct pci_dev *pci, pm_message_t state)
+{
+ struct sdio_slot **slots = pci_get_drvdata(pci);
+ struct sdio_slot **s;
+
+ if (slots) {
+ s = slots;
+ while (*s) {
+ /* Pass the event to the SDIO driver. */
+ sdio_suspend(*s);
+ s++;
+ }
+ }
+
+ return 0;
+}
+
+static int shc_pci_resume(struct pci_dev *pci)
+{
+ int ret;
+ struct sdio_slot **slots = pci_get_drvdata(pci);
+ struct sdio_slot **s;
+
+ ret = 0;
+ if (slots) {
+ s = slots;
+ while (*s) {
+ struct shc_data *shc = (*s)->drv_data;
+ /* Re-initialise h/w. */
+ ret = shc_hw_init(shc);
+ if (ret != 0) {
+ break;
+ }
+ /* Pass the event to the SDIO driver. */
+ sdio_resume(*s);
+ s++;
+ }
+ }
+
+ return ret;
+}
+
+
+#ifndef PCI_CLASS_SYSTEM_SDHCI
+#define PCI_CLASS_SYSTEM_SDHCI 0x0805
+#endif
+
+static struct pci_device_id shc_pci_id_table[] = {
+ {
+ .vendor = PCI_VENDOR_ID_RICOH,
+ .device = PCI_DEVICE_ID_RICOH_R5C822,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = SHC_QUIRK_DMA_DWORD_ALIGNED_ONLY | SLOT_SHC_QUIRK_R5B_BROKEN,
+ },
+ /* The Arasan SHC card does not meet the rise time requirement for
+ * high speed mode so high speed mode is very unreliable. */
+ {
+ PCI_DEVICE(0x1095, 0x0670),
+ .driver_data = SLOT_SHC_QUIRK_HIGH_SPD_BROKEN
+ | SLOT_SHC_QUIRK_DATA_TIMEOUT_USES_SDCLK,
+ },
+ { PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) },
+ { 0 },
+};
+MODULE_DEVICE_TABLE(pci, shc_pci_id_table);
+
+static struct pci_driver shc_pci_driver = {
+ .name = "slot_shc",
+ .id_table = shc_pci_id_table,
+ .probe = shc_pci_probe,
+ .remove = __devexit_p(shc_pci_remove),
+ .suspend = shc_pci_suspend,
+ .resume = shc_pci_resume,
+};
+
+static int __init shc_pci_init(void)
+{
+ return pci_register_driver(&shc_pci_driver);
+}
+
+static void __exit shc_pci_exit(void)
+{
+ pci_unregister_driver(&shc_pci_driver);
+}
+
+module_init(shc_pci_init);
+module_exit(shc_pci_exit);
+
+MODULE_DESCRIPTION("PCI SHC slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_spi_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_spi_lx.c
new file mode 100644
index 0000000..6da12f5
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_spi_lx.c
@@ -0,0 +1,734 @@
+/*
+ * Linux SDIO-SPI/CSPI slot driver.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/kernel-compat.h>
+#include <linux/jiffies.h>
+
+#include <sdioemb/cspi.h>
+#include <sdioemb/sdio_api.h>
+#include <sdioemb/slot_api.h>
+
+#include "slot_spi_lx.h"
+
+/* Length (in units of 8 clocks) of the initialization sequence. */
+#define SDIO_SPI_INIT_SEQ_LEN 10 /* = 80 clocks */
+
+/* SDIO-SPI bus timings in units of 8 clocks */
+#define SDIO_SPI_N_CR_MAX 8 /* max. time between command and response */
+#define SDIO_SPI_N_EC_MIN 0 /* min. time after response and CS inactive */
+
+/* Command and response lengths in bytes */
+#define SDIO_SPI_CMD_LEN 6
+#define SDIO_SPI_R1_LEN 1
+#define SDIO_SPI_R4_LEN 5
+#define SDIO_SPI_R5_LEN 2
+
+/* SDIO-SPI response bits */
+#define SDIO_SPI_R1_IDLE 0x01
+
+/* SDIO-SPI command bits */
+#define CMD53_W_FLAG 0x80000000
+#define CMD53_BLOCK_MODE 0x08000000
+
+#define CMD53_CRC_LEN 2
+#define CMD53_D_RESP_LEN 8
+
+/* CMD53 SDIO_SPI state machine states */
+enum spi_cmd53_sm_states {
+ CMD53_STATE_AFTER_CMD_WRITE,
+ CMD53_STATE_POLL_RESPONSE,
+ CMD53_STATE_AFTER_RESPONSE,
+ CMD53_STATE_POLL_DATA_READ,
+ CMD53_STATE_WRITE_DATA_BLOCK,
+ CMD53_STATE_READ_DATA_BLOCK,
+ CMD53_STATE_DATA_WRITE_COMPLETED,
+};
+
+/* CMD53 SDIO_SPI state machine data */
+struct spi_cmd53_sm_data {
+ int status;
+ int prev;
+ uint8_t *data_p;
+ int blocks_remaining;
+ int block_size;
+ int n_cr;
+ unsigned long timeout;
+};
+
+struct sdio_spi_controller {
+ struct spi_device *spi;
+ struct sdio_cmd *current_cmd;
+ struct spi_message spi_msg;
+ struct spi_transfer spi_trans;
+ void *transfer_buf;
+ struct spi_cmd53_sm_data cmd53_sm;
+};
+
+/*
+ * For testing purposes we can enable big-endian CSPI burst transfers
+ * with the cspi_big_endian module parameter. It's not possible to
+ * use big-endian CSPI register accesses without knowing if the
+ * register is 16 bit or 8 bit, therefore there's no need to test
+ * them.
+ */
+static int cspi_big_endian = 0;
+static void sdio_spi_cmd53_state_machine(void *context);
+
+module_param(cspi_big_endian, int, 0444);
+MODULE_PARM_DESC(cspi_big_endian, "1 = use big-endian mode for CPSI");
+
+static void cspi_memcpy_data(void *dest, const void *src, size_t n, u8 cspi_cmd)
+{
+ if (cspi_big_endian) {
+ int i;
+ u8 *d = dest;
+ const u8 *s = src;
+
+ for (i = 0; i <= (n-2); i += 2) {
+ d[i] = s[i+1];
+ d[i+1] = s[i];
+ }
+ /* odd length, handle the last octet */
+ if (i != n) {
+ if (cspi_cmd & CSPI_WRITE) {
+ d[i] = 0x00;
+ d[i+1] = s[i];
+ } else {
+ d[i] = s[i+1];
+ }
+ }
+ } else {
+ memcpy(dest, src, n);
+ }
+}
+
+static void cspi_cmd_complete(void *context)
+{
+ struct sdio_slot *slot = context;
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+ struct spi_transfer *t;
+ uint8_t *rx;
+ uint8_t resp = 0;
+
+ if (sdioc->spi_msg.status) {
+ cmd->status = SDD_CMD_ERR_CMD_OTHER;
+ } else {
+
+ t = list_entry(sdioc->spi_msg.transfers.next, struct spi_transfer, transfer_list);
+ rx = t->rx_buf;
+
+ switch (cmd->cspi.cmd & CSPI_TYPE_MASK) {
+ case CSPI_READ:
+ resp = rx[4 + slot->cspi_reg_pad];
+ cmd->cspi.val = rx[4 + slot->cspi_reg_pad + 1]
+ | (rx[4 + slot->cspi_reg_pad + 2] << 8);
+ break;
+ case CSPI_WRITE:
+ resp = rx[4];
+ break;
+ case CSPI_READ | CSPI_BURST:
+ resp = rx[6 + slot->cspi_burst_pad];
+ cspi_memcpy_data(cmd->data, rx + 6+slot->cspi_burst_pad+1, cmd->len, CSPI_READ);
+ break;
+ case CSPI_WRITE | CSPI_BURST:
+ resp = rx[6];
+ break;
+ }
+ cmd->cspi.response = resp;
+
+ if (resp) {
+ cmd->status = SDD_CMD_ERR_DAT_OTHER;
+ } else {
+ cmd->status = SDD_CMD_OK;
+ }
+ }
+
+ sdio_cmd_complete(slot, cmd);
+}
+
+static int cspi_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+ struct spi_message *m = &sdioc->spi_msg;
+ struct spi_transfer *t;
+ size_t transfer_len;
+ uint8_t *tx;
+ int ret = -ENOMEM;
+
+ if (cmd->cspi.cmd & CSPI_BURST) {
+ /* Big-endian CSPI data transfers must be multiple of two. */
+ size_t data_len = cmd->len;
+ if (cspi_big_endian)
+ data_len += (cmd->len & 1);
+ transfer_len = 1 + 3 + 2 + data_len; /* cmd + addr + len + data */
+ if (cmd->cspi.cmd & CSPI_READ) {
+ transfer_len += 1 + slot->cspi_burst_pad; /* status byte + padding */
+ }
+ } else {
+ transfer_len = 1 + 3 + 2; /* cmd + addr + data */
+ if (cmd->cspi.cmd & CSPI_READ) {
+ transfer_len += 1 + slot->cspi_reg_pad; /* status byte + padding */
+ }
+ }
+
+ t = list_entry(m->transfers.next, struct spi_transfer, transfer_list);
+ tx = (uint8_t *)t->tx_buf;
+
+ tx[0] = cmd->cspi.cmd;
+ tx[1] = (cmd->cspi.addr >> 16) & 0xff;
+ tx[2] = (cmd->cspi.addr >> 8) & 0xff;
+ tx[3] = (cmd->cspi.addr >> 0) & 0xff;
+ if (cmd->cspi.cmd & CSPI_BURST) { /* FIXME: set bit to omit len? */
+ tx[4] = (cmd->len >> 8) & 0xff;
+ tx[5] = (cmd->len >> 0) & 0xff;
+ if (cmd->cspi.cmd & CSPI_WRITE) {
+ cspi_memcpy_data(tx + 6, cmd->data, cmd->len, CSPI_WRITE);
+ }
+ } else if (cmd->cspi.cmd & CSPI_WRITE) {
+ tx[4] = (cmd->cspi.val >> 0) & 0xff;
+ tx[5] = (cmd->cspi.val >> 8) & 0xff;
+ }
+
+ t->len = transfer_len;
+ m->complete = cspi_cmd_complete;
+ m->context = slot;
+
+ ret = spi_async(sdioc->spi, m);
+ if (ret < 0) {
+ dev_dbg(&sdioc->spi->dev, "%s: failed: ret = %d\n", __FUNCTION__, ret);
+ }
+
+ return ret;
+}
+
+
+static void sdio_spi_cmd_complete(void *context)
+{
+ struct sdio_slot *slot = context;
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+ struct spi_transfer *t;
+ uint8_t *rx;
+ uint8_t r1;
+ int i;
+
+ t = list_entry(sdioc->spi_msg.transfers.next, struct spi_transfer, transfer_list);
+ rx = t->rx_buf;
+
+ /* Skip over the init sequence for CMD0s. */
+ if (cmd->sdio.cmd == 0) {
+ rx += SDIO_SPI_INIT_SEQ_LEN;
+ }
+
+ /* Find response. */
+ for (i = 0; i <= SDIO_SPI_N_CR_MAX; i++) {
+ r1 = rx[SDIO_SPI_CMD_LEN+i];
+ if (r1 != 0xff) {
+ break;
+ }
+ }
+ if (i > SDIO_SPI_N_CR_MAX) {
+ dev_dbg(&sdioc->spi->dev, "no response\n");
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ } else {
+ cmd->status = SDD_CMD_OK;
+
+ if (r1 & ~SDIO_SPI_R1_IDLE) {
+ dev_dbg(&sdioc->spi->dev, "error in response (R1 = 0x%02x)\n", r1);
+ cmd->status = SDD_CMD_ERR_CMD_OTHER;
+ }
+ switch (cmd->sdio.cmd) {
+ case 5:
+ cmd->sdio.response.r4 =
+ (rx[SDIO_SPI_CMD_LEN+i+1] << 24) |
+ (rx[SDIO_SPI_CMD_LEN+i+2] << 16) |
+ (rx[SDIO_SPI_CMD_LEN+i+3] << 8) |
+ (rx[SDIO_SPI_CMD_LEN+i+4] << 0);
+ break;
+ case 52:
+ cmd->sdio.response.r5 = rx[SDIO_SPI_CMD_LEN+i+1];
+ break;
+ }
+ }
+
+ sdio_cmd_complete(slot, cmd);
+}
+
+static int spi_nbytes_transfer(struct sdio_slot *slot, int n_bytes)
+{
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+ struct spi_message *m = &sdioc->spi_msg;
+ struct spi_transfer *t;
+ uint8_t *tx;
+ int ret;
+
+ t = list_entry(m->transfers.next, struct spi_transfer, transfer_list);
+ tx = (uint8_t *)t->tx_buf;
+
+ memset(tx, 0xff, n_bytes);
+
+ t->len = n_bytes;
+ m->complete = sdio_spi_cmd53_state_machine;
+ m->context = slot;
+
+ ret = spi_async(sdioc->spi, m);
+ if (ret < 0) {
+ dev_dbg(&sdioc->spi->dev, "%s: failed: ret = %d\n", __FUNCTION__, ret);
+ }
+ return ret;
+}
+
+static int cmd53_check_data_response_and_busy(uint8_t *rx, int t_len)
+{
+ int i, k;
+ for (i = 0; i < CMD53_D_RESP_LEN; i++) {
+
+ if ((rx[t_len - CMD53_D_RESP_LEN + i] & 0x1f) == 0x5) {
+ /* Data Block Response is OK. */
+
+ for (k = i + 1; k < CMD53_D_RESP_LEN +1 ; k++) {
+
+ if ((rx[t_len - CMD53_D_RESP_LEN + k] & 0xff) != 0) {
+ /* Busy is finished */
+ return 0;
+ }
+ }
+ }
+ }
+ /* Error condition. */
+ return 1;
+}
+
+static void sdio_spi_cmd53_state_machine(void *context)
+{
+ struct sdio_slot *slot = context;
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+ struct sdio_cmd *cmd = sdioc->current_cmd;
+ struct spi_message *m = &sdioc->spi_msg;
+ struct spi_transfer *t;
+ uint8_t *rx;
+ uint8_t *tx;
+ uint8_t val;
+ int ret;
+
+ t = list_entry(sdioc->spi_msg.transfers.next, struct spi_transfer, transfer_list);
+ rx = t->rx_buf;
+ tx = (uint8_t *)t->tx_buf;
+
+ switch (sdioc->cmd53_sm.status) {
+
+ case CMD53_STATE_AFTER_CMD_WRITE:
+ sdioc->cmd53_sm.n_cr = 0;
+ sdioc->cmd53_sm.status = CMD53_STATE_POLL_RESPONSE;
+ spi_nbytes_transfer(slot, 1);
+ break;
+
+ case CMD53_STATE_POLL_RESPONSE:
+ sdioc->cmd53_sm.n_cr++;
+ val = rx[0];
+ if (val != 0xff) {
+ /* Check the response. */
+ if (sdioc->cmd53_sm.n_cr > SDIO_SPI_N_CR_MAX) {
+ dev_dbg(&sdioc->spi->dev, "no response\n");
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ sdio_cmd_complete(slot, cmd);
+ } else {
+ cmd->status = SDD_CMD_OK;
+
+ if (val & ~SDIO_SPI_R1_IDLE) {
+ dev_dbg(&sdioc->spi->dev, "error in response (VAL = 0x%02x)\n", val);
+ cmd->status = SDD_CMD_ERR_CMD_OTHER;
+ } else {
+ sdioc->cmd53_sm.prev = sdioc->cmd53_sm.status;
+ /* Response is ok, we can go further. */
+ if (cmd->sdio.arg & CMD53_W_FLAG) {
+ sdioc->cmd53_sm.status = CMD53_STATE_WRITE_DATA_BLOCK;
+ } else {
+ sdioc->cmd53_sm.status = CMD53_STATE_AFTER_RESPONSE;
+ }
+ if (cmd->sdio.arg & CMD53_BLOCK_MODE) {
+ sdioc->cmd53_sm.blocks_remaining = cmd->sdio.arg & 0x1ff;
+ sdioc->cmd53_sm.block_size = (cmd->len) / (cmd->sdio.arg & 0x1ff);
+ } else {
+ sdioc->cmd53_sm.blocks_remaining = 0;
+ sdioc->cmd53_sm.block_size = cmd->sdio.arg & 0x1ff;
+ }
+ sdioc->cmd53_sm.data_p = cmd->data;
+ spi_nbytes_transfer(slot, 1);
+ }
+ }
+ } else {
+ /* Continue to poll. */
+ spi_nbytes_transfer(slot, 1);
+ }
+ break;
+
+ case CMD53_STATE_WRITE_DATA_BLOCK:
+ if (sdioc->cmd53_sm.prev == CMD53_STATE_WRITE_DATA_BLOCK) {
+ /* Check the previous block transfer. */
+ if (cmd53_check_data_response_and_busy(rx, t->len) == 0) {
+ cmd->status = SDD_CMD_OK;
+ } else {
+ cmd->status = SDD_CMD_ERR_DAT_OTHER;
+ sdio_cmd_complete(slot, cmd);
+ break;
+ }
+ } else {
+ sdioc->cmd53_sm.prev = CMD53_STATE_WRITE_DATA_BLOCK;
+ }
+
+ t->len = 0;
+
+ /* Write data block. */
+ *tx = 0xff; /* wait 1 byte */
+ tx++;
+ t->len += 1;
+
+ if (cmd->sdio.arg & CMD53_BLOCK_MODE) {
+ if( ( cmd->sdio.arg & 0x1ff ) > 1 )
+ *tx = 0xfc; /* start token */
+ else
+ *tx = 0xfe; /* start token */
+ tx++;
+ } else {
+ *tx = 0xfe;
+ tx++;
+ }
+ t->len += 1;
+
+ /* Data block. */
+ memcpy(tx, sdioc->cmd53_sm.data_p, sdioc->cmd53_sm.block_size); /* data */
+ tx += sdioc->cmd53_sm.block_size;
+ t->len += sdioc->cmd53_sm.block_size;
+ sdioc->cmd53_sm.data_p += sdioc->cmd53_sm.block_size;
+
+ /* CRC */
+ memset(tx, 0xff, CMD53_CRC_LEN);
+ tx += CMD53_CRC_LEN;
+ t->len += CMD53_CRC_LEN;
+
+ /* data response */
+ memset(tx, 0xff, CMD53_D_RESP_LEN);
+ tx += CMD53_D_RESP_LEN;
+ t->len += CMD53_D_RESP_LEN;
+
+ m->complete = sdio_spi_cmd53_state_machine;
+ m->context = slot;
+
+ ret = spi_async(sdioc->spi, m);
+ if (ret < 0) {
+ dev_dbg(&sdioc->spi->dev, "%s: failed: ret = %d\n", __FUNCTION__, ret);
+ }
+ if (sdioc->cmd53_sm.blocks_remaining > 1) {
+ sdioc->cmd53_sm.blocks_remaining--;
+ } else {
+ sdioc->cmd53_sm.status = CMD53_STATE_DATA_WRITE_COMPLETED;
+ }
+ break;
+
+ case CMD53_STATE_AFTER_RESPONSE:
+ /* Activate timeout. */
+ sdioc->cmd53_sm.timeout = jiffies + HZ; /* 1 sec timout. */
+
+ /* Read secon byte of response and start to poll. */
+ sdioc->cmd53_sm.status = CMD53_STATE_POLL_DATA_READ;
+ spi_nbytes_transfer(slot, 1);
+ break;
+
+ case CMD53_STATE_POLL_DATA_READ:
+ val = rx[0];
+ if (val == 0xfe) {
+ sdioc->cmd53_sm.status = CMD53_STATE_READ_DATA_BLOCK;
+ spi_nbytes_transfer(slot, sdioc->cmd53_sm.block_size + CMD53_CRC_LEN);
+ } else {
+ if (time_after(jiffies, sdioc->cmd53_sm.timeout)) {
+ dev_dbg(&sdioc->spi->dev, "no data\n");
+ cmd->status = SDD_CMD_ERR_CMD_TIMEOUT;
+ sdio_cmd_complete(slot, cmd);
+ } else {
+ /* Continue to poll. */
+ spi_nbytes_transfer(slot, 1);
+ }
+ }
+ break;
+
+ case CMD53_STATE_READ_DATA_BLOCK:
+ memcpy(sdioc->cmd53_sm.data_p, rx, sdioc->cmd53_sm.block_size);
+ if (sdioc->cmd53_sm.blocks_remaining > 1) {
+
+ sdioc->cmd53_sm.blocks_remaining--;
+ sdioc->cmd53_sm.data_p += (sdioc->cmd53_sm.block_size);
+
+ /* Activate timeout. */
+ sdioc->cmd53_sm.timeout = jiffies + HZ; /* 1 sec timout. */
+
+ /* Poll for the next block. */
+ sdioc->cmd53_sm.status = CMD53_STATE_POLL_DATA_READ;
+ spi_nbytes_transfer(slot, 1);
+ } else {
+ sdio_cmd_complete(slot, cmd); ;
+ }
+ break;
+
+ case CMD53_STATE_DATA_WRITE_COMPLETED:
+ if (cmd53_check_data_response_and_busy(rx, t->len) == 0) {
+ cmd->status = SDD_CMD_OK;
+ sdio_cmd_complete(slot, cmd);
+ break;
+ }
+ cmd->status = SDD_CMD_ERR_DAT_OTHER;
+ sdio_cmd_complete(slot, cmd);
+ break;
+
+ default:
+ dev_dbg(&sdioc->spi->dev, "%s State Machine state not defined\n", __FUNCTION__);
+ }
+}
+
+static int sdio_spi_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+ struct spi_message *m = &sdioc->spi_msg;
+ struct spi_transfer *t;
+ size_t transfer_len;
+ uint8_t *tx;
+ int ret = -ENOMEM;
+
+ sdioc->current_cmd = cmd;
+
+ if (cmd->flags & SDD_CMD_FLAG_CSPI) {
+ return cspi_start_cmd(slot, cmd);
+ }
+
+ transfer_len = SDIO_SPI_CMD_LEN + SDIO_SPI_N_CR_MAX;
+ switch (cmd->sdio.cmd) {
+ case 0:
+ transfer_len += SDIO_SPI_R1_LEN;
+ break;
+ case 5:
+ transfer_len += SDIO_SPI_R4_LEN;
+ break;
+ case 52:
+ transfer_len += SDIO_SPI_R5_LEN;
+ break;
+ case 53:
+ /* Just send the 6 bytes command. */
+ transfer_len = SDIO_SPI_CMD_LEN;
+ break;
+ default:
+ dev_err(&sdioc->spi->dev, "CMD%d not supported\n", cmd->sdio.cmd);
+ return -EINVAL;
+ };
+ transfer_len += SDIO_SPI_N_EC_MIN;
+
+ t = list_entry(m->transfers.next, struct spi_transfer, transfer_list);
+ tx = (uint8_t *)t->tx_buf;
+
+ /* Add the init sequence to CMD0s. */
+ if (cmd->sdio.cmd == 0) {
+ memset(tx, 0xff, SDIO_SPI_INIT_SEQ_LEN);
+ tx += SDIO_SPI_INIT_SEQ_LEN;
+ transfer_len += SDIO_SPI_INIT_SEQ_LEN;
+ }
+
+ tx[0] = 0x40 | cmd->sdio.cmd;
+ tx[1] = (cmd->sdio.arg >> 24) & 0xff;
+ tx[2] = (cmd->sdio.arg >> 16) & 0xff;
+ tx[3] = (cmd->sdio.arg >> 8) & 0xff;
+ tx[4] = (cmd->sdio.arg >> 0) & 0xff;
+ tx[5] = 0x01 | 0x94; /* CRC for CMD0, ignored for other commands */
+ memset(tx + SDIO_SPI_CMD_LEN, 0xff, transfer_len - SDIO_SPI_CMD_LEN);
+
+ t->len = transfer_len;
+ if (cmd->sdio.cmd == 53) {
+ m->complete = sdio_spi_cmd53_state_machine;
+ sdioc->cmd53_sm.status = CMD53_STATE_AFTER_CMD_WRITE;
+ } else {
+ m->complete = sdio_spi_cmd_complete;
+ }
+ m->context = slot;
+
+ ret = spi_async(sdioc->spi, m);
+ if (ret < 0) {
+ dev_dbg(&sdioc->spi->dev, "%s: failed: ret = %d\n", __FUNCTION__, ret);
+ }
+
+ return ret;
+}
+
+static int sdio_spi_card_power(struct sdio_slot *slot, enum sdio_power pwr)
+{
+ return 0;
+}
+
+static int sdio_spi_card_present(struct sdio_slot *slot)
+{
+ return 1;
+}
+
+/*
+ * With edge triggered interrupts there's no need to mask the
+ * interrupt signal as a new interrupt will only be triggered when the
+ * device asserts the interrupt again after it's cleared.
+ */
+/* FIXME: This should be in platform data. */
+
+static void sdio_spi_enable_card_int(struct sdio_slot *slot)
+{
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+ struct spi_device *spidev = sdioc->spi;
+ struct sdio_spi_plat_data *spipd = spidev->dev.platform_data;
+
+ spipd->enable_int(slot);
+}
+
+static void sdio_spi_disable_card_int(struct sdio_slot *slot)
+{
+}
+
+static irqreturn_t sdio_spi_int_handler(int irq, void *dev_id)
+{
+ struct spi_device *spi = dev_id;
+ struct sdio_slot *slot = dev_get_drvdata(&spi->dev);
+
+ sdio_interrupt(slot);
+
+ return IRQ_HANDLED;
+}
+
+static int sdio_spi_set_bus_freq(struct sdio_slot *slot, int clk)
+{
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+
+ if( clk == SDD_BUS_FREQ_OFF ||
+ clk == SDD_BUS_FREQ_DEFAULT ||
+ clk == SDD_BUS_FREQ_IDLE ) {
+ /* None of these apply to SPI as the clock will be stopped whenever there is
+ * no data
+ */
+ return 0;
+ }
+
+ sdioc->spi->max_speed_hz = clk;
+
+ return sdioc->spi->master->setup( sdioc->spi );
+}
+
+static int __devinit sdio_spi_probe(struct spi_device *spi)
+{
+ struct sdio_slot *slot;
+ struct sdio_spi_controller *sdioc;
+ int ret;
+
+ slot = sdio_slot_alloc(sizeof(struct sdio_spi_controller));
+ if (!slot) {
+ return -ENOMEM;
+ }
+ dev_set_drvdata(&spi->dev, slot);
+
+ strcpy(slot->name, spi->dev.bus_id);
+ slot->type = SDD_SLOT_TYPE_SPI_CSPI;
+ slot->start_cmd = sdio_spi_start_cmd;
+ slot->card_present = sdio_spi_card_present;
+ slot->card_power = sdio_spi_card_power;
+ slot->enable_card_int = sdio_spi_enable_card_int;
+ slot->set_bus_freq = sdio_spi_set_bus_freq;
+ slot->disable_card_int = sdio_spi_disable_card_int;
+ slot->caps.max_bus_width = 1;
+ slot->caps.cspi_mode = CSPI_MODE_LEN_FIELD_PRESENT;
+ if (cspi_big_endian) {
+ slot->caps.cspi_mode |= CSPI_MODE_BE_BURST;
+ }
+
+ sdioc = slot->drv_data;
+
+ sdioc->spi = spi;
+ sdioc->transfer_buf = (void *)__get_free_page(GFP_KERNEL);
+ if (!sdioc->transfer_buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* Initialize a SPI message with a single transfer. */
+ spi_message_init(&sdioc->spi_msg);
+ sdioc->spi_msg.context = slot;
+ sdioc->spi_trans.tx_buf = sdioc->transfer_buf;
+ sdioc->spi_trans.rx_buf = sdioc->transfer_buf + PAGE_SIZE/2;
+ sdioc->spi_trans.cs_change = 1;
+ sdioc->spi_trans.delay_usecs = 0;
+ spi_message_add_tail(&sdioc->spi_trans, &sdioc->spi_msg);
+
+ ret = request_irq(spi->irq, sdio_spi_int_handler, 0, spi->dev.bus_id, spi);
+ if (ret) {
+ goto err;
+ }
+
+ ret = sdio_slot_register(slot);
+ if (ret) {
+ goto err_slot_reg;
+ }
+
+ return 0;
+
+ err_slot_reg:
+ free_irq(spi->irq, spi);
+ err:
+ if (sdioc->transfer_buf)
+ free_page((unsigned long)sdioc->transfer_buf);
+ sdio_slot_free(slot);
+ return ret;
+}
+
+static int __devexit sdio_spi_remove(struct spi_device *spi)
+{
+ struct sdio_slot *slot = dev_get_drvdata(&spi->dev);
+ struct sdio_spi_controller *sdioc = slot->drv_data;
+
+ sdio_slot_unregister(slot);
+ free_irq(spi->irq, spi);
+ free_page((unsigned long)sdioc->transfer_buf);
+ sdio_slot_free(slot);
+
+ return 0;
+}
+
+static struct spi_driver sdio_spi_driver = {
+ .driver = {
+ .name = "slot_spi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = sdio_spi_probe,
+ .remove = __devexit_p(sdio_spi_remove),
+};
+
+static int __init slot_spi_init(void)
+{
+ return spi_register_driver(&sdio_spi_driver);
+}
+module_init(slot_spi_init);
+
+static void __exit slot_spi_exit(void)
+{
+ spi_unregister_driver(&sdio_spi_driver);
+}
+module_exit(slot_spi_exit);
+
+MODULE_DESCRIPTION("SDIO-SPI and CSPI slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_spi_lx.h b/unifi_hostsw_linux_147/sdioemb/slot_spi_lx.h
new file mode 100644
index 0000000..4745c12
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_spi_lx.h
@@ -0,0 +1,19 @@
+/*
+ * Linux sdio spi private data definitions.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#ifndef _SLOT_SPI_LX_H
+#define _SLOT_SPI_LX_H
+
+struct sdio_spi_plat_data {
+ struct work_struct spi_work;
+ struct sdio_slot *slot;
+ int (*enable_int)(struct sdio_slot *);
+ int (*disable_int)(struct sdio_slot *);
+};
+
+#endif /* #ifndef _SLOT_SPI_LX_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_ushc_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_ushc_lx.c
new file mode 100644
index 0000000..790bf61
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_ushc_lx.c
@@ -0,0 +1,538 @@
+/*
+ * Linux USB SD Host Controller (USHC) slot driver.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * References:
+ * [USHC] USB SD Host Controller specification (CS-118793-SP)
+ */
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+
+#include <sdioemb/sdio.h>
+#include <sdioemb/slot_api.h>
+
+enum ushc_request {
+ USHC_GET_CAPS = 0x00,
+ USHC_HOST_CTRL = 0x01,
+ USHC_PWR_CTRL = 0x02,
+ USHC_CLK_FREQ = 0x03,
+ USHC_EXEC_CMD = 0x04,
+ USHC_READ_RESP = 0x05,
+};
+
+enum ushc_request_type {
+ USHC_GET_CAPS_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_HOST_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_PWR_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_CLK_FREQ_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_EXEC_CMD_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USHC_READ_RESP_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+};
+
+#define USHC_GET_CAPS_3V3 (1 << 8)
+#define USHC_GET_CAPS_3V0 (1 << 9)
+#define USHC_GET_CAPS_1V8 (1 << 10)
+#define USHC_GET_CAPS_HIGH_SPD (1 << 16)
+
+#define USHC_HOST_CTRL_4BIT (1 << 1)
+#define USHC_HOST_CTRL_HIGH_SPD (1 << 0)
+
+#define USHC_PWR_CTRL_OFF 0x00
+#define USHC_PWR_CTRL_3V3 0x01
+#define USHC_PWR_CTRL_3V0 0x02
+#define USHC_PWR_CTRL_1V8 0x03
+
+#define USHC_READ_RESP_BUSY (1 << 4)
+#define USHC_READ_RESP_ERR_TIMEOUT (1 << 3)
+#define USHC_READ_RESP_ERR_CRC (1 << 2)
+#define USHC_READ_RESP_ERR_DAT (1 << 1)
+#define USHC_READ_RESP_ERR_CMD (1 << 0)
+#define USHC_READ_RESP_ERR_MASK 0x0f
+
+struct ushc_exec_cmd_req {
+ u8 bRequestType;
+ u8 bRequest;
+ u8 cmd_idx;
+ u8 reserved;
+ __le16 block_size;
+ __le16 wLength;
+};
+
+struct ushc_exec_cmd_data {
+ __le32 arg;
+};
+
+struct ushc_read_resp_req {
+ u8 bRequestType;
+ u8 bRequest;
+ u8 reserved[4];
+ __le16 wLength;
+};
+
+struct ushc_read_resp_data {
+ u8 status;
+ u8 reserved[3];
+ __le32 resp;
+};
+
+#define USHC_INT_STATUS_SDIO_INT (1 << 1)
+#define USHC_INT_STATUS_CARD_PRESENT (1 << 0)
+
+struct ushc_int_data {
+ u8 status;
+ u8 reserved[3];
+};
+
+struct ushc_data {
+ struct usb_device *usb_dev;
+
+ struct urb *int_urb;
+ struct ushc_int_data *int_data;
+
+ struct urb *cmd_urb;
+ struct ushc_exec_cmd_req *cmd_req;
+ struct ushc_exec_cmd_data *cmd_data;
+
+ struct urb *data_urb;
+
+ struct urb *resp_urb;
+ struct ushc_read_resp_req *resp_req;
+ struct ushc_read_resp_data *resp_data;
+
+ spinlock_t lock;
+ struct sdio_cmd *current_cmd;
+ u32 caps;
+ u16 host_ctrl;
+ int disconnected;
+ int int_enabled;
+};
+
+static void data_callback(struct urb *urb);
+
+static int ushc_hw_get_caps(struct ushc_data *ushc)
+{
+ int ret;
+
+ ret = usb_control_msg(ushc->usb_dev, usb_rcvctrlpipe(ushc->usb_dev, 0),
+ USHC_GET_CAPS, USHC_GET_CAPS_TYPE,
+ 0, 0, &ushc->caps, sizeof(ushc->caps), 100);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ushc->caps = le32_to_cpu(ushc->caps);
+ return 0;
+}
+
+
+static int ushc_hw_set_host_ctrl(struct ushc_data *ushc, u16 mask, u16 val)
+{
+ u16 host_ctrl;
+ int ret;
+
+ host_ctrl = (ushc->host_ctrl & ~mask) | val;
+ ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
+ USHC_HOST_CTRL, USHC_HOST_CTRL_TYPE,
+ host_ctrl, 0, NULL, 0, 100);
+ if (ret >= 0) {
+ ushc->host_ctrl = host_ctrl;
+ }
+ return ret;
+}
+
+static void int_callback(struct urb *urb)
+{
+ struct sdio_slot *slot = urb->context;
+ struct ushc_data *ushc = slot->drv_data;
+
+ if (ushc->int_data->status & USHC_INT_STATUS_SDIO_INT
+ && ushc->int_enabled) {
+ sdio_interrupt(slot);
+ }
+
+ if (ushc->int_urb->status == 0) {
+ usb_submit_urb(ushc->int_urb, GFP_ATOMIC);
+ }
+}
+
+static void cmd_callback(struct urb *urb)
+{
+ struct sdio_slot *slot = urb->context;
+ struct ushc_data *ushc = slot->drv_data;
+ struct sdio_cmd *cmd = ushc->current_cmd;
+ int ret;
+
+ if (cmd->data) {
+ int pipe;
+
+ if (cmd->flags & SDD_CMD_FLAG_READ)
+ pipe = usb_rcvbulkpipe(ushc->usb_dev, 6);
+ else
+ pipe = usb_sndbulkpipe(ushc->usb_dev, 2);
+
+ usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe,
+ cmd->data, cmd->len, data_callback, slot);
+ ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC);
+ if (ret < 0) {
+ usb_unlink_urb(ushc->resp_urb);
+ }
+ }
+}
+
+static void resp_callback(struct urb *urb)
+{
+ struct sdio_slot *slot = urb->context;
+ struct ushc_data *ushc = slot->drv_data;
+ struct sdio_cmd *cmd = ushc->current_cmd;
+ int status;
+ int ret;
+
+ status = ushc->resp_data->status;
+
+ if (urb->status != 0) {
+ cmd->status = SDD_CMD_ERR_CMD_OTHER;
+ } else if (status & USHC_READ_RESP_BUSY) {
+ ret = usb_submit_urb(ushc->resp_urb, GFP_ATOMIC);
+ if (ret < 0) {
+ cmd->status = SDD_CMD_ERR_CMD_OTHER;
+ } else {
+ return;
+ }
+ } else if (status & USHC_READ_RESP_ERR_MASK) {
+ if (status & USHC_READ_RESP_ERR_DAT) {
+ cmd->status = SDD_CMD_ERR_DAT;
+ } else {
+ cmd->status = SDD_CMD_ERR_CMD;
+ }
+ if (status & USHC_READ_RESP_ERR_CRC) {
+ cmd->status |= SDD_CMD_ERR_CRC;
+ }
+ if (status & USHC_READ_RESP_ERR_TIMEOUT) {
+ cmd->status |= SDD_CMD_ERR_TIMEOUT;
+ }
+ usb_unlink_urb(ushc->data_urb);
+ }
+
+ if (cmd->status == SDD_CMD_IN_PROGRESS) {
+ cmd->status = SDD_CMD_OK;
+ }
+
+ cmd->sdio.response.r1 = le32_to_cpu(ushc->resp_data->resp);
+
+ sdio_cmd_complete(slot, cmd);
+}
+
+static void data_callback(struct urb *urb)
+{
+ struct sdio_slot *slot = urb->context;
+ struct ushc_data *ushc = slot->drv_data;
+
+ if (urb->status != 0) {
+ usb_unlink_urb(ushc->resp_urb);
+ }
+}
+
+
+static int ushc_start_cmd(struct sdio_slot *slot, struct sdio_cmd *cmd)
+{
+ struct ushc_data *ushc = slot->drv_data;
+ struct urb *cmd_urb = ushc->cmd_urb;
+ int ret;
+
+ spin_lock(&ushc->lock);
+
+ if (ushc->disconnected) {
+ cmd->status = SDD_CMD_ERR_NO_CARD;
+ sdio_cmd_complete(slot, cmd);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ushc->current_cmd = cmd;
+
+ /* fill urb(s) */
+ ushc->cmd_req->cmd_idx = cmd->sdio.cmd;
+ ushc->cmd_req->block_size = cpu_to_le16(cmd->owner->blocksize);
+ ushc->cmd_data->arg = cpu_to_le32(cmd->sdio.arg);
+ printk("%x\n", ushc->cmd_data->arg);
+
+ /* start cmd with ctrl (+ bulk urb) */
+ ret = usb_submit_urb(cmd_urb, GFP_ATOMIC);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = usb_submit_urb(ushc->resp_urb, GFP_ATOMIC);
+ if (ret < 0) {
+ usb_unlink_urb(cmd_urb);
+ goto out;
+ }
+
+out:
+ spin_unlock(&ushc->lock);
+ return ret;
+}
+
+static int ushc_set_bus_freq(struct sdio_slot *slot, int clk)
+{
+ struct ushc_data *ushc = slot->drv_data;
+ int ret;
+
+ /* Hardware can't detect interrupts while the clock is off. */
+ if (clk == SDD_BUS_FREQ_IDLE) {
+ clk = 400000;
+ }
+
+ ret = ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_HIGH_SPD,
+ clk > SDIO_CLOCK_FREQ_NORMAL_SPD ? USHC_HOST_CTRL_HIGH_SPD : 0);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* FIXME: shouldn't sleep here! */
+ ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
+ USHC_CLK_FREQ, USHC_CLK_FREQ_TYPE,
+ clk & 0xffff, (clk >> 16) & 0xffff, NULL, 0, 100);
+ if (ret >= 0) {
+ ret = clk;
+ }
+ return ret;
+}
+
+static int ushc_set_bus_width(struct sdio_slot *slot, int bus_width)
+{
+ struct ushc_data *ushc = slot->drv_data;
+
+ return ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_4BIT,
+ bus_width == 4 ? USHC_HOST_CTRL_4BIT : 0);
+}
+
+static int ushc_card_power(struct sdio_slot *slot, enum sdio_power power)
+{
+ struct ushc_data *ushc = slot->drv_data;
+ u16 voltage;
+
+ switch (power) {
+ case SDIO_POWER_OFF:
+ voltage = USHC_PWR_CTRL_OFF;
+ break;
+ case SDIO_POWER_3V3:
+ if (!(ushc->caps & USHC_GET_CAPS_3V3)) {
+ return -ENOTSUPP;
+ }
+ voltage = USHC_PWR_CTRL_3V3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
+ USHC_PWR_CTRL, USHC_PWR_CTRL_TYPE,
+ voltage, 0, NULL, 0, 100);
+}
+
+static int ushc_card_present(struct sdio_slot *slot)
+{
+ struct ushc_data *ushc = slot->drv_data;
+
+ return ushc->int_data->status & USHC_INT_STATUS_CARD_PRESENT;
+}
+
+static void ushc_enable_card_int(struct sdio_slot *slot)
+{
+ struct ushc_data *ushc = slot->drv_data;
+
+ ushc->int_enabled = 1;
+}
+
+static void ushc_disable_card_int(struct sdio_slot *slot)
+{
+ struct ushc_data *ushc = slot->drv_data;
+
+ ushc->int_enabled = 0;
+}
+
+static void ushc_clean_up(struct sdio_slot *slot)
+{
+ struct ushc_data *ushc = slot->drv_data;
+
+ usb_free_urb(ushc->int_urb);
+ usb_free_urb(ushc->cmd_urb);
+ usb_free_urb(ushc->resp_urb);
+
+ kfree(ushc->int_data);
+ kfree(ushc->cmd_data);
+ kfree(ushc->cmd_req);
+ kfree(ushc->resp_data);
+ kfree(ushc->resp_req);
+}
+
+static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ struct sdio_slot *slot;
+ struct ushc_data *ushc;
+ int ret = -ENOMEM;
+
+ slot = sdio_slot_alloc(sizeof(struct ushc_data));
+ if (slot == NULL) {
+ return -ENOMEM;
+ }
+ ushc = slot->drv_data;
+ usb_set_intfdata(intf, slot);
+
+ ushc->usb_dev = usb_dev;
+
+ strlcpy(slot->name, usb_dev->dev.bus_id, sizeof(slot->name));
+ slot->set_bus_freq = ushc_set_bus_freq;
+ slot->set_bus_width = ushc_set_bus_width;
+ slot->start_cmd = ushc_start_cmd;
+ slot->card_present = ushc_card_present;
+ slot->card_power = ushc_card_power;
+ slot->enable_card_int = ushc_enable_card_int;
+ slot->disable_card_int = ushc_disable_card_int;
+
+ spin_lock_init(&ushc->lock);
+
+ /* Read capabilities. */
+ ret = ushc_hw_get_caps(ushc);
+ if (ret < 0) {
+ goto err;
+ }
+ slot->caps.max_bus_freq = (ushc->caps & USHC_GET_CAPS_HIGH_SPD)
+ ? SDIO_CLOCK_FREQ_HIGH_SPD : SDIO_CLOCK_FREQ_NORMAL_SPD;
+ slot->caps.max_bus_width = 4;
+
+ ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->int_urb == NULL) {
+ goto err;
+ }
+ ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL);
+ if (ushc->int_data == NULL) {
+ goto err;
+ }
+ usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,
+ usb_rcvintpipe(usb_dev,
+ intf->cur_altsetting->endpoint[0].desc.bEndpointAddress),
+ ushc->int_data, sizeof(struct ushc_int_data),
+ int_callback, slot,
+ intf->cur_altsetting->endpoint[0].desc.bInterval);
+
+ ushc->cmd_req = kzalloc(sizeof(struct ushc_exec_cmd_req), GFP_KERNEL);
+ if (ushc->cmd_req == NULL) {
+ goto err;
+ }
+ ushc->cmd_data = kzalloc(sizeof(struct ushc_exec_cmd_data), GFP_KERNEL);
+ if (ushc->cmd_data == NULL) {
+ goto err;
+ }
+ ushc->cmd_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->cmd_urb == NULL) {
+ goto err;
+ }
+ ushc->cmd_req->bRequestType = USHC_EXEC_CMD_TYPE;
+ ushc->cmd_req->bRequest = USHC_EXEC_CMD;
+ ushc->cmd_req->wLength = cpu_to_le16(sizeof(struct ushc_exec_cmd_data));
+ usb_fill_control_urb(ushc->cmd_urb, ushc->usb_dev, usb_sndctrlpipe(usb_dev, 0),
+ (void *)ushc->cmd_req,
+ ushc->cmd_data, sizeof(struct ushc_exec_cmd_data),
+ cmd_callback, slot);
+
+ ushc->resp_req = kzalloc(sizeof(struct ushc_read_resp_req), GFP_KERNEL);
+ if (ushc->resp_req == NULL) {
+ goto err;
+ }
+ ushc->resp_data = kzalloc(sizeof(struct ushc_read_resp_data), GFP_KERNEL);
+ if (ushc->resp_data == NULL) {
+ goto err;
+ }
+ ushc->resp_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->cmd_urb == NULL) {
+ goto err;
+ }
+ ushc->resp_req->bRequestType = USHC_READ_RESP_TYPE;
+ ushc->resp_req->bRequest = USHC_READ_RESP;
+ ushc->resp_req->wLength = cpu_to_le16(sizeof(struct ushc_read_resp_data));
+ usb_fill_control_urb(ushc->resp_urb, ushc->usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ (void *)ushc->resp_req,
+ ushc->resp_data, sizeof(struct ushc_read_resp_data),
+ resp_callback, slot);
+
+ ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (ushc->data_urb == NULL) {
+ goto err;
+ }
+
+ ret = sdio_slot_register(slot);
+ if (ret) {
+ goto err;
+ }
+
+ ret = usb_submit_urb(ushc->int_urb, GFP_KERNEL);
+ if (ret < 0) {
+ sdio_slot_unregister(slot);
+ goto err;
+ }
+
+ return 0;
+
+ err:
+ ushc_clean_up(slot);
+ sdio_slot_free(slot);
+ return ret;
+}
+
+static void ushc_disconnect(struct usb_interface *intf)
+{
+ struct sdio_slot *slot = usb_get_intfdata(intf);
+ struct ushc_data *ushc = slot->drv_data;
+
+ spin_lock(&ushc->lock);
+ ushc->disconnected = 1;
+ spin_unlock(&ushc->lock);
+
+ usb_kill_urb(ushc->int_urb);
+ usb_kill_urb(ushc->cmd_urb);
+ usb_kill_urb(ushc->data_urb);
+ usb_kill_urb(ushc->resp_urb);
+
+ sdio_slot_unregister(slot);
+
+ ushc_clean_up(slot);
+}
+
+static struct usb_device_id ushc_id_table[] = {
+ /* CSR USB SD Host Controller */
+ { USB_DEVICE(0x0a12, 0x5d10) }, /* FIXME: real device ID TBD */
+ { USB_DEVICE(0x04b4, 0x4611) },
+ { },
+};
+
+static struct usb_driver ushc_driver = {
+ .name = "slot_ushc",
+ .id_table = ushc_id_table,
+ .probe = ushc_probe,
+ .disconnect = ushc_disconnect,
+};
+
+static int __init ushc_init(void)
+{
+ return usb_register(&ushc_driver);
+}
+module_init(ushc_init);
+
+static void __exit ushc_exit(void)
+{
+ usb_deregister(&ushc_driver);
+}
+module_exit(ushc_exit);
+
+MODULE_DESCRIPTION("USB SD Host Controller slot driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/slot_zeus_lx.c b/unifi_hostsw_linux_147/sdioemb/slot_zeus_lx.c
new file mode 100644
index 0000000..40ce883
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/slot_zeus_lx.c
@@ -0,0 +1,172 @@
+/*
+ * Arcom ZEUS SDIO and SDIO-SPI/CSPI controller devices.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx_spi.h>
+#include <asm/arch/zeus.h>
+
+#include "slot_pxa27x_lx.h"
+#include "slot_spi_lx.h"
+
+static int zeus_sdio_card_present(struct device *dev)
+{
+ return !(GPLR(ZEUS_MMC_CD_GPIO) & GPIO_bit(ZEUS_MMC_CD_GPIO));
+}
+
+static int zeus_sdio_card_power(struct device *dev, enum sdio_power power)
+{
+ /* Power is always enabled on the ZEUS. */
+ return 0;
+}
+
+void zeus_irq_work(struct work_struct *work)
+{
+ struct zeus_sdio_spi_plat_data *zeus_spdata =
+ container_of(work, struct zeus_sdio_spi_plat_data, irq_work);
+ struct sdio_slot *slot = container_of(zeus_spdata, struct sdio_slot, slot);
+
+ sdio_interrupt(slot);
+}
+
+static int zeus_sdio_spi_enable_int(struct sdio_slot *slot)
+{
+ /* Check if interrupt line is LOW and in case schedule a work queue */
+ if (!GPLR(98)) {
+ zeus_sdio_spi_plat_data->slot = slot;
+ schedule_work(&zeus_sdio_spi_plat_data->irq_work);
+ }
+ return 0;
+}
+
+static struct pxa27x_sdio_plat_data zeus_sdio_plat_data = {
+ .card_present = zeus_sdio_card_present,
+ .card_power = zeus_sdio_card_power,
+};
+
+struct sdio_spi_plat_data zeus_sdio_spi_plat_data = {
+ .enable_int = zeus_sdio_spi_enable_int,
+}
+/*
+ * For SDIO-SPI/CSPI use the PXA270's SSP1 SPI controller. The signals
+ * for this are available on the camera interface connector (J9).
+ *
+ * SDIO-SPI PXA270 PXA270
+ * signal Signal GPIO J9 pin
+ * ---------------------------------------
+ * SCLK SSPSCLK 23 3 (CIF_MCLK)
+ * CS SSPSFRM 24 6 (CIF_FV)
+ * DI SSPTxD 25 5 (CIF_LV)
+ * DO SSPRxD 26 4 (CIF_PCLK)
+ * IRQ GPIO98 98 7 (CIF_DD0)
+ */
+#define ZEUS_SDIO_SPI_INT_GPIO 98
+
+/* SSP1 SPI master. */
+static struct resource pxa2xx_spi_ssp1_resources[] = {
+ [0] = {
+ .start = __PREG(SSCR0_P(1)),
+ .end = __PREG(SSCR0_P(1)) + 0x2c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP,
+ .end = IRQ_SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct pxa2xx_spi_master pxa2xx_spi_ssp1_master_info = {
+ .ssp_type = PXA27x_SSP1,
+ .clock_enable = CKEN3_SSP,
+ .num_chipselect = 1,
+ .enable_dma = 1,
+};
+
+/* SDIO-SPI/CSPI capable SPI device. */
+static struct pxa2xx_spi_chip sdio_spi_chip_info = {
+ .tx_threshold = 8,
+ .rx_threshold = 8,
+ .dma_burst_size = 8,
+ .timeout_microsecs = 64,
+};
+
+static struct spi_board_info zeus_spi_board_info = {
+ .modalias = "slot_spi",
+ .max_speed_hz = 20000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &zeus_sdio_spi_plat_data,
+ .controller_data = &sdio_spi_chip_info,
+ .irq = IRQ_GPIO(ZEUS_SDIO_SPI_INT_GPIO),
+};
+
+static struct platform_device zeus_sdio_devices[] = {
+ {
+ .name = "pxa27x-sdio",
+ .id = 0,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &zeus_sdio_plat_data,
+ },
+ },
+ {
+ .name = "pxa2xx-spi",
+#define SSP1_ID 1
+ .id = SSP1_ID,
+ .resource = pxa2xx_spi_ssp1_resources,
+ .num_resources = ARRAY_SIZE(pxa2xx_spi_ssp1_resources),
+ .dev = {
+ .platform_data = &pxa2xx_spi_ssp1_master_info,
+ },
+ },
+};
+
+static int __init slot_zeus_init(void)
+{
+ int i;
+ struct spi_master *master = NULL;
+
+ /* SPI pins */
+ pxa_gpio_mode(GPIO23_SCLK_MD);
+ pxa_gpio_mode(GPIO24_SFRM_MD);
+ pxa_gpio_mode(GPIO25_STXD_MD);
+ pxa_gpio_mode(GPIO26_SRXD_MD);
+ pxa_gpio_mode(ZEUS_SDIO_SPI_INT_GPIO | GPIO_IN);
+ set_irq_type(IRQ_GPIO(ZEUS_SDIO_SPI_INT_GPIO), IRQT_FALLING);
+
+ for (i = 0; i < ARRAY_SIZE(zeus_sdio_devices); i++) {
+ platform_device_register(&zeus_sdio_devices[i]);
+ }
+
+ master = spi_busnum_to_master(SSP1_ID);
+ if (!master) {
+ printk(KERN_WARNING "slot_zeus: no SPI master\n");
+ goto out;
+ }
+ spi_new_device(spi_busnum_to_master(SSP1_ID), &zeus_spi_board_info);
+
+ INIT_WORK(&zeus_sdio_spi_plat_data->irq_work, zeus_irq_work);
+
+ out:
+ if (master)
+ spi_master_put(master);
+ return 0;
+}
+
+module_init(slot_zeus_init);
+
+MODULE_DESCRIPTION("Arcom ZEUS SDIO and SDIO-SPI/CSPI slot devices.");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/000_card_info.c b/unifi_hostsw_linux_147/sdioemb/tests/000_card_info.c
new file mode 100644
index 0000000..da20535
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/000_card_info.c
@@ -0,0 +1,100 @@
+/*
+ * 000_card_info - test reading card info.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Tests reading manufacturer ID, card ID, number of functions and
+ * function interface and max block size.
+ */
+#include "sdd_test.h"
+
+struct card_info {
+ uint16_t manf_id;
+ uint16_t card_id;
+ int num_funcs;
+ struct {
+ uint8_t std_if;
+ int max_block_size;
+ } func[SDIO_MAX_FUNCTIONS];
+};
+
+static struct card_info card_info[] = {
+ {
+ .manf_id = SDIO_MANF_ID_CSR,
+ .card_id = SDIO_CARD_ID_CSR_BC6,
+ .num_funcs = 2,
+ .func[0] = {
+ .std_if = 0,
+ .max_block_size = 0,
+ },
+ .func[1] = {
+ .std_if = SDIO_STD_IFACE_BT_TYPE_A,
+ .max_block_size = 512,
+ },
+ .func[2] = {
+ .std_if = 0,
+ .max_block_size = 0,
+ },
+ },
+};
+
+#define NUM_CARDS (sizeof(card_info)/sizeof(card_info[0]))
+
+static void test_000_card_info(sdio_uif_t uif, void *arg)
+{
+ uint16_t manf_id;
+ uint16_t card_id;
+ int num_funcs;
+ int c, f;
+
+ manf_id = sdio_manf_id(uif);
+ if (manf_id == 0)
+ sdd_test_fail("manufacturer ID == 0");
+ card_id = sdio_card_id(uif);
+ if (card_id == 0)
+ sdd_test_fail("card ID == 0");
+
+ for (c = 0; c < NUM_CARDS; c++) {
+ if (manf_id == card_info[c].manf_id
+ && card_id == card_info[c].card_id) {
+ break;
+ }
+ }
+ if (c == NUM_CARDS) {
+ sdd_test_abort("card %04:%04x not recognized", manf_id, card_id);
+ }
+
+ num_funcs = sdio_num_functions(uif);
+ if (num_funcs != card_info[c].num_funcs) {
+ sdd_test_fail("num funcs (%d) != expected (%d)",
+ num_funcs, card_info[c].num_funcs);
+ }
+
+ for (f = 0; f <= num_funcs; f++) {
+ uint8_t std_if;
+ int max_block_size;
+
+ std_if = sdio_std_if(uif, f);
+ if (std_if != card_info[c].func[f].std_if) {
+ sdd_test_fail("F%d: std if (%02x) != expected (%02x)",
+ f, std_if, card_info[c].func[f].std_if);
+ }
+
+ max_block_size = sdio_max_block_size(uif, f);
+ if (max_block_size != card_info[c].func[f].max_block_size) {
+ sdd_test_fail("F%d: max block size (%d) != expected (%d)",
+ f, max_block_size, card_info[c].func[f].max_block_size);
+ }
+ }
+
+ sdd_test_pass();
+}
+
+int main(int argc, char *argv[])
+{
+ return sdd_test_run(SDD_TEST_NAME, argc, argv,
+ test_000_card_info, NULL, NULL, NULL);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/001_block_size.c b/unifi_hostsw_linux_147/sdioemb/tests/001_block_size.c
new file mode 100644
index 0000000..9601c4f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/001_block_size.c
@@ -0,0 +1,77 @@
+/*
+ * 001_block_size - test set/get block size.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Tests setting default and power of two block sizes from 8 to maximum
+ * supported by card.
+ */
+#include "sdd_test.h"
+
+static void test_001_block_size(sdio_uif_t uif, void *arg)
+{
+ int num_funcs;
+ int f;
+
+ num_funcs = sdio_num_functions(uif);
+
+ for (f = 0; f <= num_funcs; f++) {
+ int max_block_size;
+ int block_size;
+ int new_block_size;
+ int ret;
+
+ max_block_size = sdio_max_block_size(uif, f);
+
+ if (max_block_size == 0) {
+ continue;
+ }
+
+ /*
+ * Test block sizes up to the maximum.
+ */
+ for (block_size = 4; block_size <= max_block_size; block_size *= 2) {
+ ret = sdio_set_block_size(uif, f, block_size);
+ if (ret < 0) {
+ sdd_test_fail("F%d: set block size to %d", f, block_size);
+ }
+
+ new_block_size = sdio_block_size(uif, f);
+ if (new_block_size != block_size) {
+ sdd_test_fail("F%d: new block size (%d) != requested block size %d\n",
+ f, new_block_size, block_size);
+ }
+ }
+
+ /*
+ * Set default block size and check it's the expected size.
+ */
+ ret = sdio_set_block_size(uif, f, 0);
+ if (ret < 0) {
+ sdd_test_fail("F%d: set block size to default", f);
+ }
+
+ if (max_block_size > 512) {
+ block_size = 512;
+ } else {
+ block_size = max_block_size;
+ }
+
+ new_block_size = sdio_block_size(uif, f);
+ if (new_block_size != block_size) {
+ sdd_test_fail("F%d: new block size (%d) != requested block size %d\n",
+ f, new_block_size, block_size);
+ }
+ }
+
+ sdd_test_pass();
+}
+
+int main(int argc, char *argv[])
+{
+ return sdd_test_run(SDD_TEST_NAME, argc, argv,
+ test_001_block_size, NULL, NULL, NULL);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/002_cmd52.c b/unifi_hostsw_linux_147/sdioemb/tests/002_cmd52.c
new file mode 100644
index 0000000..56e305f
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/002_cmd52.c
@@ -0,0 +1,53 @@
+/*
+ * 002_cmd52 - test CMD52 reads and writes.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Tests CMD52 reads and writes using the CSR_FROM_HOST_SCRATCH0
+ * register.
+ */
+#include "sdd_test.h"
+
+static const struct sdd_test_card supported_cards[] = {
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_BC6, "BC6", },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH_D00, "dash (d00)", },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH, "dash", },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_CINDERELLA, "cinderella", },
+ { },
+};
+
+static void test_002_cmd52(sdio_uif_t uif, void *arg)
+{
+ int i;
+ int ret;
+
+ sdd_test_check_cards(supported_cards);
+
+ for (i = 0; i < sdd_test_max_iters(); i++) {
+ uint8_t r;
+
+ ret = sdio_write8(uif, 0, SDIO_CSR_FROM_HOST_SCRATCH0, i & 0xff);
+ if (ret < 0) {
+ sdd_test_fail("sdio_write8");
+ }
+
+ ret = sdio_read8(uif, 0, SDIO_CSR_FROM_HOST_SCRATCH0, &r);
+ if (ret < 0) {
+ sdd_test_fail("sdio_read8");
+ }
+ if (r != (i & 0xff)) {
+ sdd_test_fail("data read (%d) != expected value (%d)", r, i & 0xff);
+ }
+ }
+
+ sdd_test_pass();
+}
+
+int main(int argc, char *argv[])
+{
+ return sdd_test_run(SDD_TEST_NAME, argc, argv,
+ test_002_cmd52, NULL, NULL, NULL);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/003_cmd52_async.c b/unifi_hostsw_linux_147/sdioemb/tests/003_cmd52_async.c
new file mode 100644
index 0000000..b1cd34c
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/003_cmd52_async.c
@@ -0,0 +1,93 @@
+/*
+ * 003_cmd52_async - test CMD52 asynchronous reads and writes.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Tests asynchronous CMD52 reads and writes using the
+ * CSR_FROM_HOST_SCRATCH0 register.
+ */
+#include <string.h>
+
+#include "sdd_test.h"
+
+static const struct sdd_test_card supported_cards[] = {
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_BC6, "BC6", },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH_D00, "dash (d00)", },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH, "dash", },
+ { },
+};
+
+struct state {
+ int i;
+ uint8_t data;
+};
+
+static void cmd52_write_done(sdio_uif_t uif, void *arg, int status);
+static void cmd52_read_done(sdio_uif_t uif, void *arg, int status);
+
+static void test_003_cmd52_async(sdio_uif_t uif, void *arg)
+{
+ struct state *state;
+ int ret;
+
+ sdd_test_check_cards(supported_cards);
+
+ state = malloc(sizeof(struct state));
+
+ state->i = 0;
+ state->data = 0xff;
+
+ ret = sdio_write8_async(uif, 0, SDIO_CSR_FROM_HOST_SCRATCH0, state->i & 0xff,
+ cmd52_write_done, state);
+ if (ret < 0) {
+ sdd_test_fail("sdio_write8_async");
+ }
+}
+
+static void cmd52_write_done(sdio_uif_t uif, void *arg, int status)
+{
+ struct state *state = arg;
+ int ret;
+
+ if (status < 0) {
+ sdd_test_fail("CMD52 write failed: %s", strerror(-status));
+ }
+
+ ret = sdio_read8_async(uif, 0, SDIO_CSR_FROM_HOST_SCRATCH0, &state->data,
+ cmd52_read_done, state);
+ if (ret < 0) {
+ sdd_test_fail("sdio_read8_async");
+ }
+}
+
+static void cmd52_read_done(sdio_uif_t uif, void *arg, int status)
+{
+ struct state *state = arg;
+ int ret;
+
+ if (status < 0) {
+ sdd_test_fail("CMD52 read failed: %s", strerror(-status));
+ }
+ if (state->data != (state->i & 0xff)) {
+ sdd_test_fail("data read (%d) != expected value (%d)", state->data, state->i & 0xff);
+ }
+
+ if (++state->i < sdd_test_max_iters()) {
+ ret = sdio_write8_async(uif, 0, SDIO_CSR_FROM_HOST_SCRATCH0, state->i & 0xff,
+ cmd52_write_done, state);
+ if (ret < 0) {
+ sdd_test_fail("sdio_write8_async");
+ }
+ } else {
+ sdd_test_pass();
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ return sdd_test_run(SDD_TEST_NAME, argc, argv,
+ test_003_cmd52_async, NULL, NULL, NULL);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/004_interrupt.c b/unifi_hostsw_linux_147/sdioemb/tests/004_interrupt.c
new file mode 100644
index 0000000..08f4685
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/004_interrupt.c
@@ -0,0 +1,105 @@
+/*
+ * 004_interrupt - test SDIO interrupt
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Tests SDIO interrupts.
+ */
+#include <time.h>
+#include <semaphore.h>
+#include <errno.h>
+
+#include "sdd_test.h"
+
+struct test_card {
+ int generic_func;
+ uint32_t sdio_host_int;
+};
+
+#define BC6_SDIO_HOST_INT (0xFC24 << 1)
+#define DASH_SDIO_HOST_INT (0xF92F << 1)
+
+static struct test_card bc6_data = {
+ .generic_func = 2,
+ .sdio_host_int = BC6_SDIO_HOST_INT,
+};
+
+static struct test_card dash_data = {
+ .generic_func = 2,
+ .sdio_host_int = DASH_SDIO_HOST_INT,
+};
+
+static const struct sdd_test_card supported_cards[] = {
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_BC6, "BC6", &bc6_data },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH_D00, "dash (d00)", &dash_data },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH, "dash", &dash_data },
+ { },
+};
+
+struct state {
+ sem_t int_sem;
+};
+
+static void clear_int(sdio_uif_t uif)
+{
+ sdio_write8(uif, 0, SDIO_CSR_HOST_INT, 1);
+}
+
+static void int_handler(sdio_uif_t uif, void *arg)
+{
+ struct state *state = arg;
+
+ clear_int(uif);
+ sem_post(&state->int_sem);
+}
+
+static void test_004_interrupt(sdio_uif_t uif, void *arg)
+{
+ struct test_card *card;
+ struct state *state = arg;
+ struct timespec timeout;
+ int i;
+ int failed = 0;
+ int ret;
+
+ card = sdd_test_check_cards(supported_cards);
+
+ sdio_write8(uif, 0, SDIO_CCCR_IO_EN, 1 << card->generic_func);
+
+ for (i = 0; i < sdd_test_max_iters(); i++) {
+ if (sdio_write8(uif, card->generic_func, card->sdio_host_int, 1) < 0) {
+ sdd_test_abort("write to SDIO_HOST_INT");
+ }
+
+ clock_gettime(CLOCK_REALTIME, &timeout);
+ timeout.tv_sec += 1;
+ ret = sem_timedwait(&state->int_sem, &timeout);
+ if (ret < 0) {
+ if (errno == ETIMEDOUT) {
+ clear_int(uif);
+ failed++;
+ } else {
+ sdd_test_abort("waiting for interrupt");
+ }
+ }
+ }
+ if (failed) {
+ sdd_test_fail("%d out of %d interrupts missed", failed, sdd_test_max_iters());
+ }
+
+ sdd_test_pass();
+}
+
+int main(int argc, char *argv[])
+{
+ struct state state;
+
+ sem_init(&state.int_sem, 0, 0);
+
+ return sdd_test_run(SDD_TEST_NAME, argc, argv,
+ test_004_interrupt, &state,
+ int_handler, &state);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/005_int_mask.c b/unifi_hostsw_linux_147/sdioemb/tests/005_int_mask.c
new file mode 100644
index 0000000..b3b2019
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/005_int_mask.c
@@ -0,0 +1,113 @@
+/*
+ * 005_int_mask - test interrupt mask and unmask.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Tests interrupts can be correctly masked and unmasked by counting
+ * the number of times the interrupt handler is called.
+ */
+#include <time.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "sdd_test.h"
+
+struct test_card {
+ int generic_func;
+ uint32_t sdio_host_int;
+};
+
+#define BC6_SDIO_HOST_INT (0xFC24 << 1)
+#define DASH_SDIO_HOST_INT (0xF92F << 1)
+
+static struct test_card bc6_data = {
+ .generic_func = 2,
+ .sdio_host_int = BC6_SDIO_HOST_INT,
+};
+
+static struct test_card dash_data = {
+ .generic_func = 2,
+ .sdio_host_int = DASH_SDIO_HOST_INT,
+};
+
+static const struct sdd_test_card supported_cards[] = {
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_BC6, "BC6", &bc6_data },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH_D00, "dash (d00)", &dash_data },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH, "dash", &dash_data },
+ { },
+};
+
+struct state {
+ sem_t int_sem;
+ int int_count;
+};
+
+static void int_handler(sdio_uif_t uif, void *arg)
+{
+ struct state *state = arg;
+
+ state->int_count++;
+
+ sdio_interrupt_mask(uif);
+
+ sem_post(&state->int_sem);
+}
+
+static void test_005_int_mask(sdio_uif_t uif, void *arg)
+{
+ struct test_card *card;
+ struct state *state = arg;
+ struct timespec timeout;
+ int i;
+ int ret;
+
+ card = sdd_test_check_cards(supported_cards);
+
+ sdio_write8(uif, 0, SDIO_CCCR_IO_EN, 1 << card->generic_func);
+
+ for (i = 0; i < sdd_test_max_iters(); i++) {
+ if (sdio_write8(uif, card->generic_func, card->sdio_host_int, 1) < 0) {
+ sdd_test_abort("write to SDIO_HOST_INT");
+ }
+
+ clock_gettime(CLOCK_REALTIME, &timeout);
+ timeout.tv_sec += 5;
+ ret = sem_timedwait(&state->int_sem, &timeout);
+ if (ret < 0) {
+ if (errno == ETIMEDOUT) {
+ sdd_test_fail("no interrupt received");
+ }
+ sdd_test_abort("waiting for interrupt");
+ }
+
+ /* Wait a bit before clearing the interrupt, if interrupts
+ weren't masked properly the interrupt handler will be
+ spammed during this time. */
+ usleep(50000);
+ sdio_write8(uif, 0, SDIO_CSR_HOST_INT, 1);
+ sdio_interrupt_unmask(uif);
+ }
+
+ if (state->int_count != sdd_test_max_iters()) {
+ sdd_test_fail("numer of interrupts (%d) not expected (%d)",
+ state->int_count, sdd_test_max_iters());
+ }
+
+ sdd_test_pass();
+}
+
+int main(int argc, char *argv[])
+{
+ struct state state;
+
+ sem_init(&state.int_sem, 0, 0);
+ state.int_count = 0;
+
+ return sdd_test_run(SDD_TEST_NAME, argc, argv,
+ test_005_int_mask, &state,
+ int_handler, &state);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/006_cmd53.c b/unifi_hostsw_linux_147/sdioemb/tests/006_cmd53.c
new file mode 100644
index 0000000..72f13b5
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/006_cmd53.c
@@ -0,0 +1,114 @@
+/*
+ * 006_cmd53 - test CMD53 reads and writes.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Tests CMD53 reads and writes using some buffer handles available
+ * via the generic function.
+ */
+#include <string.h>
+
+#include "sdd_test.h"
+
+struct test_card {
+ int generic_func;
+ uint32_t sdio_mode;
+ int buffer_hdl_write;
+ int buffer_hdl_read;
+};
+
+#define DASH_SDIO_MODE (0xf935 << 1)
+
+static struct test_card dash_data = {
+ .generic_func = 2,
+ .sdio_mode = DASH_SDIO_MODE,
+ .buffer_hdl_write = 0x12,
+ .buffer_hdl_read = 0x13,
+};
+
+static struct test_card cinderella_data = {
+ .generic_func = 1,
+ .sdio_mode = 0,
+ .buffer_hdl_write = 0x1,
+ .buffer_hdl_read = 0x1,
+};
+
+static const struct sdd_test_card supported_cards[] = {
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH_D00, "dash (d00)", &dash_data },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_DASH, "dash", &dash_data },
+ { SDIO_MANF_ID_CSR, SDIO_CARD_ID_CSR_CINDERELLA, "cinderella", &cinderella_data },
+ { },
+};
+
+
+#define BUFFER_LEN (16*1024)
+
+
+static void test_006_cmd53(sdio_uif_t uif, void *arg)
+{
+ struct test_card *card;
+ size_t block_size;
+ int i, l;
+ int ret;
+ uint8_t *buf_out, *buf_in;
+
+ buf_out = malloc(2*BUFFER_LEN);
+ if (!buf_out) {
+ sdd_test_abort("transfer buffer");
+ }
+ buf_in = buf_out + BUFFER_LEN;
+
+ card = sdd_test_check_cards(supported_cards);
+
+ block_size = sdio_block_size(uif, card->generic_func);
+
+ sdio_write8(uif, 0, SDIO_CCCR_IO_EN, 1 << card->generic_func);
+ if (card->sdio_mode) {
+ sdio_write8(uif, card->generic_func, card->sdio_mode, 0x00);
+ }
+
+ for (i = 0; i < sdd_test_max_iters(); i++) {
+ int b;
+
+ for (l = 4; l <= 4096; l++) {
+ for (b = 0; b < l; b++) {
+ buf_out[b] = rand()/(int)(((unsigned)RAND_MAX + 1) / 256);
+ buf_in[b] = 0xaa;
+ }
+
+ ret = sdio_write(uif, card->generic_func, card->buffer_hdl_write,
+ buf_out, l, block_size);
+ if (ret < 0) {
+ sdd_test_fail("sdio_write");
+ }
+
+ ret = sdio_read(uif, card->generic_func, card->buffer_hdl_read,
+ buf_in, l, block_size);
+ if (ret < 0) {
+ sdd_test_fail("sdio_read");
+ }
+ if (sdio_card_id(uif) != SDIO_CARD_ID_CSR_CINDERELLA) {
+ if (memcmp(buf_in, buf_out, l) != 0) {
+ sdd_test_fail("read buffer != written buffer");
+ }
+ }
+ }
+ }
+
+ if (card->sdio_mode) {
+ sdio_write8(uif, card->generic_func, card->sdio_mode, 0x01);
+ }
+ if (sdio_card_id(uif) == SDIO_CARD_ID_CSR_CINDERELLA) {
+ sdd_test_abort("commands successful but data not verified");
+ }
+ sdd_test_pass();
+}
+
+int main(int argc, char *argv[])
+{
+ return sdd_test_run(SDD_TEST_NAME, argc, argv,
+ test_006_cmd53, NULL, NULL, NULL);
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/Makefile b/unifi_hostsw_linux_147/sdioemb/tests/Makefile
new file mode 100644
index 0000000..cbff7ec
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/Makefile
@@ -0,0 +1,33 @@
+TESTS := \
+ 000_card_info \
+ 001_block_size \
+ 002_cmd52 \
+ 003_cmd52_async \
+ 004_interrupt \
+ 005_int_mask \
+ 006_cmd53
+
+UIF ?= /dev/sdio_uif0
+
+CC := $(CROSS_COMPILE)gcc
+
+CFLAGS := -Wall -g -O2 -I../include
+LDLIBS := -L../libsdio -lsdio -lpthread -lrt
+
+%: %.c
+ $(CC) -o $@ $^ -D'SDD_TEST_NAME="$@"' $(CFLAGS) $(LDLIBS)
+
+all: $(TESTS)
+
+$(TESTS): sdd_test.o
+
+sdd_test.o: sdd_test.c sdd_test.h
+ $(CC) -o sdd_test.o -c sdd_test.c $(CFLAGS)
+
+test: $(TESTS)
+ @set -e; for T in $(TESTS); do \
+ sudo ./$$T $(UIF); \
+ done
+
+clean:
+ rm -f $(TESTS) sdd_test.o
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/sdd_test.c b/unifi_hostsw_linux_147/sdioemb/tests/sdd_test.c
new file mode 100644
index 0000000..74ada61
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/sdd_test.c
@@ -0,0 +1,195 @@
+/*
+ * sdioemb test infrastructure.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <semaphore.h>
+#include <time.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "sdd_test.h"
+
+struct sdd_test {
+ const char *name;
+ int argc;
+ char **argv;
+ sdio_uif_t uif;
+ sdd_test_func_t test_func;
+ void *test_arg;
+ sdio_int_handler_t int_handler;
+ void *int_arg;
+ int max_iters;
+ sem_t test_done_sem;
+ sem_t halt_test_sem;
+ int ret;
+};
+
+static struct sdd_test sdd;
+
+static void sdd_test_abort_usage()
+{
+ sdd_test_abort("usage: %s [-i <iters>] <sdio uif device> [test specific options]",
+ sdd.argv[0]);
+}
+
+static void parse_options(void)
+{
+ opterr = 0;
+
+ for (;;) {
+ unsigned n;
+
+ switch (getopt(sdd.argc, sdd.argv, "+i:")) {
+ case 'i':
+ if (sscanf(optarg, "%u", &n) < 1) {
+ sdd_test_abort("invalid parameter '%s' to -i option", optarg);
+ }
+ sdd.max_iters = n;
+ break;
+ case '?':
+ sdd_test_abort_usage();
+ break;
+ case -1:
+ sdd.argv[optind-1] = sdd.argv[0];
+ sdd.argc -= optind - 1;
+ sdd.argv += optind - 1;
+ return;
+ }
+ }
+}
+
+static void *test_thread_func(void *arg)
+{
+ parse_options();
+
+ if (sdd.argc < 2) {
+ sdd_test_abort_usage();
+ }
+
+ sdd.uif = sdio_open(sdd.argv[1], sdd.int_handler, sdd.int_arg);
+ if (sdd.uif == NULL) {
+ sdd_test_abort("%s", sdd.argv[1]);
+ }
+
+ sdd.test_func(sdd.uif, sdd.test_arg);
+
+ pthread_exit(0);
+}
+
+int sdd_test_run(const char *test, int argc, char *argv[],
+ sdd_test_func_t test_func, void *test_arg,
+ sdio_int_handler_t int_handler, void *int_arg)
+{
+ pthread_t test_thread;
+ int ret;
+
+ sdd.name = test;
+ sdd.argc = argc;
+ sdd.argv = argv;
+ sdd.test_func = test_func;
+ sdd.test_arg = test_arg;
+ sdd.int_handler = int_handler;
+ sdd.int_arg = int_arg;
+ sdd.max_iters = 10;
+
+ sem_init(&sdd.test_done_sem, 0, 0);
+ sem_init(&sdd.halt_test_sem, 0, 0);
+
+ srand(time(NULL));
+
+ ret = pthread_create(&test_thread, NULL, test_thread_func, NULL);
+ if (ret < 0) {
+ sdd_test_abort("pthread_create");
+ }
+
+ sem_wait(&sdd.test_done_sem);
+
+ if (sdd.uif) {
+ sdio_close(sdd.uif);
+ }
+ return sdd.ret;
+}
+
+static void sdd_test_exit(int ret)
+{
+ sdd.ret = ret;
+ sem_post(&sdd.test_done_sem);
+ sem_wait(&sdd.halt_test_sem);
+}
+
+void sdd_test_pass(void)
+{
+ printf("%s: PASS\n", sdd.name);
+
+ sdd_test_exit(0);
+}
+
+void sdd_test_fail(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ printf("%s: FAIL: ", sdd.name);
+ vprintf(fmt, args);
+ if (errno) {
+ printf(": %s\n", strerror(errno));
+ } else {
+ printf("\n");
+ }
+ va_end(args);
+
+ sdd_test_exit(1);
+}
+
+void sdd_test_abort(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ printf("%s: ABORT: ", sdd.name);
+ vprintf(fmt, args);
+ if (errno) {
+ printf(": %s\n", strerror(errno));
+ } else {
+ printf("\n");
+ }
+ va_end(args);
+
+ sdd_test_exit(2);
+}
+
+void *sdd_test_check_cards(const struct sdd_test_card *cards)
+{
+ const struct sdd_test_card *c;
+
+ c = cards;
+ while (c->name) {
+ if (sdio_manf_id(sdd.uif) == c->manf_id && sdio_card_id(sdd.uif) == c->card_id) {
+ return c->card_data;
+ }
+ c++;
+ }
+
+ printf("%s: INFO: supported cards are:\n", sdd.name);
+ c = cards;
+ while (c->name) {
+ printf(" %04x:%04x (%s)\n", c->manf_id, c->card_id, c->name);
+ c++;
+ }
+ sdd_test_abort("required card not present");
+ return NULL;
+}
+
+int sdd_test_max_iters(void)
+{
+ return sdd.max_iters;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tests/sdd_test.h b/unifi_hostsw_linux_147/sdioemb/tests/sdd_test.h
new file mode 100644
index 0000000..e2974ab
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tests/sdd_test.h
@@ -0,0 +1,39 @@
+#ifndef LIBSDIO_TEST_H
+#define LIBSDIO_TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+#include <sdioemb/libsdio.h>
+#include <sdioemb/sdio.h>
+#include <sdioemb/sdio_csr.h>
+
+struct sdd_test_card {
+ uint16_t manf_id;
+ uint16_t card_id;
+ const char *name;
+ void *card_data;
+};
+
+typedef void (*sdd_test_func_t)(sdio_uif_t uif, void *arg);
+
+int sdd_test_run(const char *test, int argc, char *argv[],
+ sdd_test_func_t test_func, void *test_arg,
+ sdio_int_handler_t int_handler, void *int_arg);
+
+void *sdd_test_check_cards(const struct sdd_test_card *cards);
+
+void sdd_test_pass(void);
+void sdd_test_fail(const char *fmt, ...);
+void sdd_test_abort(const char *fmt, ...);
+
+int sdd_test_max_iters(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* #ifndef LIBSDIO_TEST_H */
diff --git a/unifi_hostsw_linux_147/sdioemb/tools/Makefile b/unifi_hostsw_linux_147/sdioemb/tools/Makefile
new file mode 100644
index 0000000..3f6369d
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tools/Makefile
@@ -0,0 +1,54 @@
+CC := $(CROSS_COMPILE)gcc
+AR := $(CROSS_COMPILE)ar
+
+CFLAGS := -Wall -g -O2 -I../include
+LDFLAGS := -g
+LDLIBS := -L../libsdio -lsdio -lpthread
+
+UTILS := \
+ sdio-cmd52 \
+ sdio-dump-cis \
+ sdio-freq-ctrl \
+ sdio-reinsert \
+ sdio-set-bus-width
+
+all: $(UTILS)
+
+sdio-cmd52: sdio-cmd52.o
+ $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
+
+sdio-cmd52.o: sdio-cmd52.c ../include/sdioemb/libsdio.h ../include/linux/sdioemb/uif.h
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+sdio-dump-cis: sdio-dump-cis.o
+ $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
+
+sdio-dump-cis.o: sdio-dump-cis.c ../include/sdioemb/libsdio.h ../include/linux/sdioemb/uif.h \
+ ../include/sdioemb/sdio.h ../include/sdioemb/sdio_cis.h
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+sdio-reinsert: sdio-reinsert.o
+ $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
+
+sdio-reinsert.o: sdio-reinsert.c ../include/sdioemb/libsdio.h ../include/linux/sdioemb/uif.h
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+sdio-freq-ctrl: sdio-freq-ctrl.o
+ $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
+
+sdio-freq-ctrl.o: sdio-freq-ctrl.c ../include/sdioemb/libsdio.h ../include/linux/sdioemb/uif.h
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+sdio-set-bus-width: sdio-set-bus-width.o
+ $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS)
+
+sdio-set-bus-width.o: sdio-set-bus-width.c ../include/sdioemb/libsdio.h ../include/linux/sdioemb/uif.h
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+install:
+ install -d $(DESTDIR)$(prefix)/bin
+ install sdio-log-decode $(UTILS) \
+ $(DESTDIR)$(prefix)/bin
+
+clean:
+ rm -f *.o $(UTILS)
diff --git a/unifi_hostsw_linux_147/sdioemb/tools/sdio-cmd52.c b/unifi_hostsw_linux_147/sdioemb/tools/sdio-cmd52.c
new file mode 100644
index 0000000..90868ec
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tools/sdio-cmd52.c
@@ -0,0 +1,59 @@
+/*
+ * Utility to read/write SDIO registers with CMD52s.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sdioemb/libsdio.h>
+
+int main(int argc, char *argv[])
+{
+ sdio_uif_t sdev;
+ int func;
+ uint32_t addr;
+ uint8_t data;
+
+ if (argc < 4) {
+ fprintf(stderr, "Usage: %s <sdio device> <func> <addr> [<value>]\n",
+ argv[0]);
+ exit(1);
+ }
+
+ sdev = sdio_open(argv[1], NULL, NULL);
+ if (!sdev) {
+ perror("sdio_open");
+ exit(1);
+ }
+
+ func = strtoul(argv[2], NULL, 0);
+ addr = strtoul(argv[3], NULL, 0);
+
+ if (func > sdio_num_functions(sdev)) {
+ fprintf(stderr, "%s: function %d isn't present\n", argv[0], func);
+ exit(1);
+ }
+
+ if (argc == 4) {
+ if (sdio_read8(sdev, func, addr, &data) < 0) {
+ perror("sdio_read8");
+ exit(1);
+ }
+ printf("F%d 0x%05x -> 0x%02x\n", func, addr, data);
+ }
+
+ if (argc == 5) {
+ data = strtoul(argv[4], NULL, 0);
+ if (sdio_write8(sdev, func, addr, data) < 0) {
+ perror("sdio_write8");
+ exit(1);
+ }
+ printf("F%d 0x%05x <- 0x%02x\n", func, addr, data);
+ }
+
+ return 0;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tools/sdio-dump-cis.c b/unifi_hostsw_linux_147/sdioemb/tools/sdio-dump-cis.c
new file mode 100644
index 0000000..b34010b
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tools/sdio-dump-cis.c
@@ -0,0 +1,156 @@
+/*
+ * Utility to print the card and function CIS.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sdioemb/libsdio.h>
+#include <sdioemb/sdio.h>
+#include <sdioemb/sdio_cis.h>
+
+static const char *sdio_tpl_str(uint8_t tpl)
+{
+ static const char *tpls[256] = {
+ [CISTPL_NULL] = "NULL",
+ [CISTPL_CHECKSUM] = "CHECKSUM",
+ [CISTPL_VERS_1] = "VERS_1",
+ [CISTPL_ALTSTR] = "ALTSTR",
+ [CISTPL_MANFID] = "MANFID",
+ [CISTPL_FUNCID] = "FUNCID",
+ [CISTPL_FUNCE] = "FUNCE",
+ [CISTPL_SDIO_STD] = "SDIO_STD",
+ [CISTPL_SDIO_EXT] = "SDIO_EXT",
+ };
+
+ if (tpls[tpl] == NULL) {
+ return "UNKNOWN";
+ }
+ return tpls[tpl];
+}
+
+int sdio_cis_read_ptr_reg(sdio_uif_t uif, uint32_t addr, uint32_t *ptr)
+{
+ uint32_t cis_ptr = 0;
+ int b;
+
+ for (b = 0; b < 3; b++) {
+ uint8_t p;
+ int ret = sdio_read8(uif, 0, addr + b, &p);
+ if (ret < 0) {
+ return ret;
+ }
+ cis_ptr |= p << (b * 8);
+ }
+ *ptr = cis_ptr;
+ return 0;
+}
+
+int sdio_print_tpl(sdio_uif_t uif, uint8_t tpl, uint8_t lnk, uint32_t cis_ptr)
+{
+ int ret = 0;
+ uint8_t val;
+ int i;
+
+ printf(" %s(%02x)", sdio_tpl_str(tpl), tpl);
+ for (i = 0; i < lnk; i++) {
+ if (i % 8 == 0) {
+ printf("\n ");
+ }
+ ret = sdio_read8(uif, 0, cis_ptr++, &val);
+ if (ret < 0) {
+ break;
+ }
+ printf(" %02x", val);
+ }
+ printf("\n");
+
+ return ret;
+}
+
+int sdio_print_cis(sdio_uif_t uif, int func)
+{
+ uint32_t cis_ptr_addr;
+ uint32_t cis_ptr;
+ uint8_t tpl, lnk;
+ int ret;
+
+ if (func == 0) {
+ cis_ptr_addr = SDIO_CCCR_CIS_PTR;
+ } else {
+ cis_ptr_addr = SDIO_FBR_CIS_PTR(func);
+ }
+
+ ret = sdio_cis_read_ptr_reg(uif, cis_ptr_addr, &cis_ptr);
+ if (ret < 0) {
+ return ret;
+ }
+ if (cis_ptr < 0x1000 || cis_ptr > 0x17000) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (;;) {
+ if (cis_ptr >= 0x17000) {
+ /* A valid CIS should have a CISTPL_END so this shouldn't happen. */
+ errno = EINVAL;
+ return -1;
+ }
+
+ ret = sdio_read8(uif, 0, cis_ptr++, &tpl);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sdio_read8(uif, 0, cis_ptr++, &lnk);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (tpl == CISTPL_END) {
+ break;
+ }
+
+ ret = sdio_print_tpl(uif, tpl, lnk, cis_ptr);
+ if (ret < 0) {
+ return ret;
+ }
+
+ cis_ptr += lnk;
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ sdio_uif_t uif;
+ int func;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <sdio device>\n", argv[0]);
+ exit(1);
+ }
+
+ uif = sdio_open(argv[1], NULL, NULL);
+ if (!uif) {
+ perror("sdio_open");
+ exit(1);
+ }
+
+ for (func = 0; func <= sdio_num_functions(uif); func++) {
+ int ret;
+
+ printf("Function %d\n", func);
+ ret = sdio_print_cis(uif, func);
+ if (ret < 0) {
+ perror("sdio_print_cis");
+ exit(1);
+ }
+ }
+
+ return 0;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tools/sdio-freq-ctrl.c b/unifi_hostsw_linux_147/sdioemb/tools/sdio-freq-ctrl.c
new file mode 100644
index 0000000..53c1cca
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tools/sdio-freq-ctrl.c
@@ -0,0 +1,33 @@
+/*
+ * Utility to control the SD bus clock frequency.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sdioemb/libsdio.h>
+
+int main(int argc, char *argv[])
+{
+ sdio_uif_t sdev;
+ int freq;
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s <sdio device> <clock freq>\n", argv[0]);
+ exit(1);
+ }
+
+ sdev = sdio_open(argv[1], NULL, NULL);
+ if (!sdev) {
+ perror("sdio_open");
+ exit(1);
+ }
+ freq = atoi(argv[2]);
+ sdio_set_max_bus_freq(sdev, freq);
+
+ return 0;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tools/sdio-log-decode b/unifi_hostsw_linux_147/sdioemb/tools/sdio-log-decode
new file mode 100755
index 0000000..0db5b6e
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tools/sdio-log-decode
@@ -0,0 +1,621 @@
+#! /usr/bin/perl -w
+
+=head1 NAME
+
+sdio-log-decode - decode a SDIO event log produced by the sdioemb driver
+
+=head1 SYNOPSIS
+
+sdio-log-decode [OPTION]... [LOG] | --help
+
+=head1 OPTIONS
+
+=over
+
+=item B<-c>, B<--card>=I<CARD>
+
+Decode addresses for I<CARD>. Supported cards are: B<generic> (the default),
+B<anastasia>, B<bigfoot>, B<cinderella>, B<dash>, and B<sugarlump>.
+
+=item B<-d>, M<--data>
+
+Show the transferred data (if available).
+
+=back
+
+=head1 DESCRIPTION
+
+B<sdio-log-decode> decodes an event log produced by the sdioemb
+driver. It reads the specified file (or stdin) and outputs the
+commands with decoded arguments and responses.
+
+=head1 KEY
+
+ W - CMD52/53 or CSPI write
+ R - CMD52/53 or CSPI read
+ B - CSPI burst transfer
+ Y - CMD53 byte mode transfer
+ K - CMD53 block mode transfer
+ F - CMD53 fixed address
+ I - CMD53 incrementing address
+ c - Response CRC error
+ t - Response timeout
+ C - Data CRC error
+ T - Data timeout
+ e - Unspecified response error
+ E - Unspecified data error
+
+=cut
+
+use strict;
+use Getopt::Long qw(:config bundling);
+use Pod::Usage;
+
+my %csr_f0_vendor_regs = (
+ 0xf0 => "CSR_HOST_DEEP_SLEEP",
+ 0xf1 => "CSR_HOST_INT_CLR",
+ 0xf2 => "CSR_FROM_HOST_SCRATCH0",
+ 0xf3 => "CSR_FROM_HOST_SCRATCH1",
+ 0xf4 => "CSR_TO_HOST_SCRATCH0",
+ 0xf5 => "CSR_TO_HOST_SCRATCH1",
+ 0xf6 => "CSR_EXT_IO_ENABLE",
+ 0xf7 => "CSR_CSPI_MODE",
+ 0xf8 => "CSR_CSPI_STATUS",
+ 0xf9 => "CSR_CSPI_PADDING",
+);
+
+my %bluetooth_type_a_regs = (
+ 0x00 => "BT_TYPE_A_RD/TD",
+ 0x10 => "BT_TYPE_A_RX_PKT_CTRL",
+ 0x11 => "BT_TYPE_A_TX_PKT_CTRL",
+ 0x12 => "BT_TYPE_A_RETRY_CTRL",
+ 0x13 => "BT_TYPE_A_INT",
+ 0x14 => "BT_TYPE_A_INT_EN",
+ 0x20 => "BT_TYPE_A_BT_MODE",
+);
+
+# Special code to describe an access through one of Bigfoot or
+# Pumpkins memory windows. There are two program memory windows and
+# one shared window.
+sub print_bigfoot_gw($$)
+ {
+ my @wind = ("PM1", "PM2", "SH");
+ my @proc = ("MAC.", "PHY.", "BOTH.", "BOTH.", "");
+ my ($addr, $pages) = @_;
+ my ($off, $j) = (0);
+ my $w = int($addr / 0x4000);
+ my $p = 4;
+
+ foreach $j (@{$pages}) {
+ if ($j->{shift} >= 0) {
+ if (defined $j->{val}) {
+ $off += $j->{val} << $j->{shift};
+ } else {
+ return sprintf("%s[??%04X]", $wind[$w], $addr & 0x3fff);
+ }
+ } else {
+ if (defined $j->{val}) {
+ $p = $j->{val};
+ }
+ }
+ }
+ my $win;
+ if ($w == 2) {
+ $win = "SH";
+ } else {
+ my $hb = $off >> 21;
+ if ($hb == 0) {
+ $win = "FLASH";
+ $off &= 0xfffff;
+ } elsif ($hb == 1) {
+ $win = $proc[$p] . "P_RAM";
+ $off &= 0xfffff;
+ } else {
+ $win = "EXT RAM";
+ $off &= 0x1fffff;
+ }
+ }
+ return sprintf("%s[%06X]", $win, ($addr & 0x3fff) + $off);
+ }
+
+# Special code to describe an access through one of Anastasias memory
+# windows. There are thee generic wondows that can be used for
+# program memory accesses or for shared memory. This will probably
+# work for Cinderella.
+sub print_anas_gw($$)
+ {
+ my @proc = ("MAC.", "PHY.", "BT.", "BOTH.", "");
+ my ($addr, $pages) = @_;
+ my ($off, $j) = (0);
+ my $w = int($addr / 0x4000);
+ my $p = 4;
+
+ foreach $j (@{$pages}) {
+ if ($j->{shift} >= 0) {
+ if (defined $j->{val}) {
+ $off += $j->{val} << $j->{shift};
+ } else {
+ return sprintf("GW%d[??%04X]", $w + 1, ($addr & 0x3fff));
+ }
+ } else {
+ if (defined $j->{val}) {
+ $p = $j->{val};
+ }
+ }
+ }
+
+ $addr = ($addr & 0x3fff) + $off;
+ my $page = ($addr >> 22) & 0xf;
+
+ my @gw_area = (
+ "SHARED", "SHARED", "SHARED", "SHARED",
+ "I ROM", "I ROM", "unused", "I RAM", # Internal
+ "IO LOG", "IO LOG", "IO LOG", "IO LOG",
+ "A ROM", "A ROM", "unused", "A RAM", # Alternative
+ );
+ my @gw_bits = (
+ 24, 24, 24, 24,
+ 22, 22, 22, 22,
+ 24, 24, 24, 24,
+ 22, 22, 22, 22,
+ );
+ return sprintf("GW%d[%-7s %07X]",
+ $w + 1, $gw_area[$page],
+ ((1 << $gw_bits[$page]) - 1) & $addr);
+ }
+
+my %registers = (
+ 'generic' => {
+ 0 => {
+ 0x00 => "CCCR_CCCR_SDIO_REVISION",
+ 0x01 => "CCCR_SD_SPEC_REVISION",
+ 0x02 => "CCCR_IO_ENABLE",
+ 0x03 => "CCCR_IO_READY",
+ 0x04 => "CCCR_INT_ENABLE",
+ 0x05 => "CCCR_INT_PENDING",
+ 0x06 => "CCCR_IO_ABORT",
+ 0x07 => "CCCR_BUS_IFACE_CTRL",
+ 0x08 => "CCCR_CARD_CAPS",
+ 0x09 => "CCCR_COMMON_CIS_PTR",
+ 0x0a => "CCCR_COMMON_CIS_PTR+1",
+ 0x0b => "CCCR_COMMON_CIS_PTR+2",
+ 0x0c => "CCCR_BUS_SUSPEND",
+ 0x0d => "CCCR_FUNCTION_SELECT",
+ 0x0e => "CCCR_EXEC_FLAGS",
+ 0x0f => "CCCR_READY_FLAGS",
+ 0x10 => "CCCR_F0_BLOCK_SIZE",
+ 0x11 => "CCCR_F0_BLOCK_SIZE+1",
+ 0x12 => "CCCR_POWER_CTRL",
+ 0x13 => "CCCR_HIGH_SPEED",
+ 0x100 => "CCCR_F1_STD_IFACE",
+ 0x101 => "CCCR_F1_SID_IFACE_EXT",
+ 0x102 => "CCCR_F1_POWER_SELECT",
+ 0x109 => "CCCR_F1_CIS_PTR",
+ 0x10a => "CCCR_F1_CIS_PTR+1",
+ 0x10b => "CCCR_F1_CIS_PTR+2",
+ 0x10c => "CCCR_F1_CSA_PTR",
+ 0x10d => "CCCR_F1_CSA_PTR+1",
+ 0x10e => "CCCR_F1_CSA_PTR+2",
+ 0x110 => "CCCR_F1_BLOCK_SIZE",
+ 0x111 => "CCCR_F1_BLOCK_SIZE+1",
+ 0x200 => "CCCR_F2_STD_IFACE",
+ 0x201 => "CCCR_F2_SID_IFACE_EXT",
+ 0x202 => "CCCR_F2_POWER_SELECT",
+ 0x209 => "CCCR_F2_CIS_PTR",
+ 0x20a => "CCCR_F2_CIS_PTR+1",
+ 0x20b => "CCCR_F2_CIS_PTR+2",
+ 0x20c => "CCCR_F2_CSA_PTR",
+ 0x20d => "CCCR_F2_CSA_PTR+1",
+ 0x20e => "CCCR_F2_CSA_PTR+2",
+ 0x210 => "CCCR_F2_BLOCK_SIZE",
+ 0x211 => "CCCR_F2_BLOCK_SIZE+1",
+ },
+ },
+ 'sugarlump' => {
+ 0 => \%csr_f0_vendor_regs,
+ 1 => \%bluetooth_type_a_regs,
+ 2 => {
+ 0xFC24 << 1 => "SDIO_HOST_INT",
+ 0xFC26 << 1 => "SDIO_MODE",
+ },
+ },
+ 'bigfoot' => {
+ 1 => {
+ 0x1FD38 => "DBG_EMU_CMD",
+ 0x1FD20 => "DBG_HOST_PROC_SELECT",
+ 0x1FD18 => "DBG_HOST_STOP_STATUS",
+ 0x1FD24 => "DBG_RESET",
+ 0x1FD02 => "GBL_CHIP_VERSION",
+ 0x1FFD2 => "XAP_PCH",
+ 0x1FFD4 => "XAP_PCL",
+ 0x1FCD6 => "SHARED_MAILBOX0",
+ 0x1FCD4 => "SHARED_MAILBOX1",
+ 0x1FCD2 => "SHARED_MAILBOX2",
+ 0x1FCD0 => "SHARED_MAILBOX3",
+ 0x1FBD2 => "SHARED_MAILBOX2B",
+ 0x1FCF6 => "PROG_MEM1_PAGE",
+ 0x1FCF0 => "PROG_MEM2_PAGE",
+ 0x1FCFC => "SHARED_MEM_PAGE",
+ 0x1FCCC => "PCI_INT_EVENT",
+ 0x1FCCE => "SDIO_HOST_INT",
+ 0x1FCCA => "SHARED_IO_INTERRUPT",
+ windows => [
+ {
+ start => 0x0100,
+ end => 0x4000,
+ pfunc => \&print_bigfoot_gw,
+ page => [
+ { reg => 0xfe7b * 2, shift => 12, },
+ { reg => 0xfe7b * 2 + 1, shift => 20, },
+ { reg => 0x1fd20 , shift => -1, },
+ ]
+ },
+ {
+ start => 0x4000,
+ end => 0x8000,
+ pfunc => \&print_bigfoot_gw,
+ page => [
+ { reg => 0xfe78 * 2, shift => 12, },
+ { reg => 0xfe78 * 2 + 1, shift => 20, },
+ { reg => 0x1fd20 , shift => -1, },
+ ]
+ },
+ {
+ start => 0x8000,
+ end => 0xc000,
+ pfunc => \&print_bigfoot_gw,
+ page => [
+ { reg => 0xfe7e * 2, shift => 12, },
+ { reg => 0xfe7e * 2 + 1, shift => 20, },
+ { reg => 0x1fd20 , shift => -1, },
+ ]
+ },
+ ]
+ },
+ },
+ # UniFi Anastasia. This configuration is for an emulator build,
+ # so things might change at any time. I believe that many other
+ # chips will be broadly similar (dash, cinderella, BC7, etc.)
+ 'anastasia' => {
+ 0 => \%csr_f0_vendor_regs,
+ 1 => \%bluetooth_type_a_regs,
+ 2 => {
+ 0xf81d * 2 => "DBG_EMU_CMD",
+ 0xf81e * 2 => "DBG_HOST_PROC_SELECT",
+ 0xf81f * 2 => "DBG_HOST_STOP_STATUS",
+ 0xf82f * 2 => "DBG_RESET",
+ 0xfe81 * 2 => "GBL_CHIP_VERSION",
+ 0xffe9 * 2 => "XAP_PCH",
+ 0xffea * 2 => "XAP_PCL",
+ 0xf84b * 2 => "SHARED_MAILBOX0",
+ 0xf84c * 2 => "SHARED_MAILBOX1",
+ 0xf84d * 2 => "SHARED_MAILBOX2",
+ 0xf84e * 2 => "SHARED_MAILBOX3",
+ 0xfb94 * 2 => "SHARED_MAILBOX4",
+ 0xfb95 * 2 => "SHARED_MAILBOX5",
+ 0xfb96 * 2 => "SHARED_MAILBOX6",
+ 0xfb97 * 2 => "SHARED_MAILBOX7",
+ 0xf92f * 2 => "SDIO_HOST_INT",
+ 0xf8ac * 2 => "MMU_HOST_GW1_CONFIG",
+ 0xf8ad * 2 => "MMU_HOST_GW2_CONFIG",
+ 0xf8ae * 2 => "MMU_HOST_GW3_CONFIG",
+ # Windows allow you to define portions of the address map
+ # that are sliding windows into other areas of memory.
+ # The windows on BigFoot and Pumpkin are different from
+ # those on Anastasia. Anastasia is similar to dash, BC7
+ # and Cinderella. Each window can point into one of many
+ # different address maps - hence the need for a helper
+ # function to dislpay which area we are pointing to.
+ windows => [
+ {
+ start => 0x0100,
+ end => 0x4000,
+ pfunc => \&print_anas_gw,
+ page => [
+ { reg => 0xf8ac * 2, shift => 11, },
+ { reg => 0xf8ac * 2 + 1, shift => 19, },
+ { reg => 0xf81e * 2, shift => -1, },
+ ]
+ },
+ {
+ start => 0x4000,
+ end => 0x8000,
+ pfunc => \&print_anas_gw,
+ page => [
+ { reg => 0xf8ad * 2, shift => 11, },
+ { reg => 0xf8ad * 2 + 1, shift => 19, },
+ { reg => 0xf81e * 2, shift => -1, },
+ ]
+ },
+ {
+ start => 0x8000,
+ end => 0xc000,
+ pfunc => \&print_anas_gw,
+ page => [
+ { reg => 0xf8ae * 2, shift => 11, },
+ { reg => 0xf8ae * 2 + 1, shift => 19, },
+ { reg => 0xf81e * 2, shift => -1, },
+ ]
+ },
+ ]
+ },
+ },
+ 'dash' => {
+ 0 => \%csr_f0_vendor_regs,
+ 1 => \%bluetooth_type_a_regs,
+ 2 => {
+ },
+ },
+);
+
+my $card = "generic";
+my $show_data = 0;
+
+sub print_decoded_cmd($$$$);
+sub print_decoded_cspi($$$$$);
+sub status_symbol($);
+sub print_decoded_addr($$$);
+sub print_decoded_int_event($$);
+
+{
+ # Other names for chips
+ $registers{'pumpkin'} = $registers{'bigfoot'};
+ $registers{'cinderella'} = $registers{'anastasia'};
+
+ # The shortened vesions.
+ $registers{'bgft'} = $registers{'bigfoot'};
+ $registers{'pmkn'} = $registers{'pumpkin'};
+ $registers{'anas'} = $registers{'anastasia'};
+ $registers{'cind'} = $registers{'cinderella'};
+
+ GetOptions(
+ 'c|card=s' => \$card,
+ 'd|data' => \$show_data,
+ 'help' => sub { pod2usage( -verbose => 1 ); }
+ ) || pod2usage( -verbose => 0);
+
+ defined $registers{$card} or die "$0: unrecognized card '$card'\n";
+ $#ARGV <= 0 or pod2usage( -verbose => 0);
+
+ if ($#ARGV == -1) {
+ *LOG = *STDIN;
+ } else {
+ my $filename = shift;
+ open LOG, "<$filename" or die "$filename: $!\n";
+ }
+
+ while (my $line = <LOG>) {
+ chomp $line;
+
+ # Seq no and time
+ if ($line =~ s/^(\s*\d+\[.*\]: )//) {
+ print "$1";
+ }
+
+ if ($line =~ m/^CMD(\d\d) arg: (.+) stat: (.+) resp: (.+)$/) {
+ print_decoded_cmd(int($1), hex($2), hex($3), hex($4));
+ } elsif ($line =~ m/^CSPI cmd:(.+) addr: (.+) ...: (.+) status: (.+) resp: (.+)$/) {
+ print_decoded_cspi(hex($1), hex($2), hex($3), hex($4), hex($5));
+ } elsif($line =~ m/^(card interrupt.*): (.*)$/) {
+ print_decoded_int_event($1, hex($2));
+ } elsif ($line =~ m/0x[0-9A-F]{4}:/) {
+ if (!$show_data) {
+ next;
+ }
+ print "$line";
+ } else {
+ # Just print unrecognized lines
+ print "$line";
+ }
+
+ print "\n";
+ }
+}
+
+sub print_decoded_cmd($$$$)
+{
+ my ($cmd, $arg, $stat, $resp) = @_;
+
+ my $func = undef;
+ my $addr = undef;
+ my $data = undef;
+
+ # Command and argument
+ printf("CMD%02u %08x", $cmd, $arg);
+
+ # Decode argument for CMD52s and CMD53
+ if ($cmd == 52) {
+ $func = ($arg & 0x70000000) >> 28;
+ $addr = ($arg & 0x07fffe00) >> 9;
+
+ printf(" %s F%d %s%05x",
+ ($arg & 0x80000000) ? 'W' : 'R', # R/W
+ ($func), # function
+ ($arg & 0x08000000) ? "RAW " : "", # RAW
+ ($addr)); # address
+ if ($arg & 0x80000000) {
+ printf(" %02x", $arg & 0x000000ff);
+ $data = $arg & 0x000000ff;
+ } else {
+ printf(" --");
+ }
+ # line up responses
+ printf(" ");
+ } elsif ($cmd == 53) {
+ $func = ($arg & 0x70000000) >> 28;
+ $addr = ($arg & 0x07fffe00) >> 9;
+
+ printf(" %s F%d %s %s %05x %3d",
+ ($arg & 0x80000000) ? 'W' : 'R', # R/W
+ ($func), # function
+ ($arg & 0x08000000) ? "K" : "Y", # block/byte
+ ($arg & 0x04000000) ? "I" : "F", # fixed/incr addr
+ ($addr), # address
+ ($arg & 0x000001ff)); # count
+ } else {
+ # line up responses
+ printf(" ");
+ }
+
+ my $sym = status_symbol($stat);
+ if (defined $sym) {
+ printf(" %s", $sym);
+
+ # Response if valid
+ if ($cmd != 0 && ($stat == 0x00 || $stat & 0x02)) {
+ printf(" %08x", $resp);
+
+ # Decode R5 response for CMD52s and CMD53s
+ if ($cmd == 52 || $cmd == 53) {
+ # Data read, if available
+ if ($cmd == 52
+ && (!($arg & 0x80000000)
+ || ($arg & 0x80000000 && ($arg & 0x08000000)))) {
+ printf(" %02x", $resp & 0x0000000ff);
+ $data = $resp & 0x0000000ff;
+ } else {
+ printf(" --");
+ }
+
+ # Unexpected transfer states: DIS, CMD (during CMD53),
+ # TRN (expect during CMD53) and RFU.
+ my $state = ($resp & 0x3000) >> 12;
+
+ print " RFU" if $state == 0x3;
+ print " TRN" if $state == 0x2 && $cmd != 53;
+ print " CMD" if $state == 0x01 && $cmd == 53;
+ print " DIS" if $state == 0x00;
+
+ # Response flags
+ printf("%s%s%s%s%s",
+ ($resp & 0x00008000) ? " CRC_ERROR" : "",
+ ($resp & 0x00004000) ? " ILLEGAL_CMD" : "",
+ ($resp & 0x00000800) ? " ERROR" : "",
+ ($resp & 0x00000200) ? " FUNC_NUM" : "",
+ ($resp & 0x00000100) ? " OUT_OF_RANGE" : "");
+ }
+ } else {
+ # line up decoded addresses
+ print(" ");
+ }
+ } else {
+ # line up decoded addresses
+ print(" ");
+ }
+
+ print_decoded_addr($func, $addr, $data) if defined $addr;
+}
+
+sub print_decoded_cspi($$$$$)
+{
+ my ($cmd, $addr, $len_val, $status, $resp) = @_;
+
+ my $is_read = $cmd & 0x10;
+ my $is_burst = $cmd & 0x40;
+ my $func = $cmd & 0x0f;
+ my $data;
+
+ printf("CSPI %02x %s%s F%d %06x",
+ $cmd, $is_read ? "R" : "W", $is_burst ? "B" : " ", $func,
+ $addr);
+ if ($is_read && !$is_burst) {
+ printf(" ----");
+ } else {
+ printf(" %04x", $len_val);
+ }
+
+ my $sym = status_symbol($status);
+ if (defined $sym) {
+ printf(" %s %02x", $sym, $resp);
+ if ($is_read && !$is_burst) {
+ printf(" %04x", $len_val);
+ } else {
+ printf(" ----");
+ }
+ printf("%s%s%s",
+ ($resp & 0x04) ? " FUNC_DISABLED" : "",
+ ($resp & 0x02) ? " CLK_STOPPED" : "",
+ ($resp & 0x01) ? " ERROR" : "");
+ } else {
+ # line up decoded addresses
+ printf(" ");
+ }
+
+ print_decoded_addr($func, $addr, $data);
+}
+
+sub status_symbol($)
+{
+ # See enum sdio_cmd_status in sdio_api.h for the %stat_symbol
+ # bits.
+ my %stat_symbol = (
+ 0x00 => " ",
+ 0x11 => "c",
+ 0x21 => "t",
+ 0x41 => "e",
+ 0x12 => "C",
+ 0x22 => "T",
+ 0x42 => "E",
+ );
+ my $stat = shift;
+
+ my $sym = $stat_symbol{$stat};
+ if (!defined $sym && $stat != 0xff) {
+ $sym = "?"; # invalid status
+ }
+ return $sym;
+}
+
+sub print_decoded_addr($$$)
+{
+ my ($func, $addr, $data) = @_;
+ my $reg = undef;
+ my ($i, $j);
+
+ $reg = $registers{$card}{$func}{$addr};
+
+ if (!defined $reg && $addr & 0x01) {
+ $reg = $registers{$card}{$func}{$addr & ~1};
+ if (defined $reg) {
+ $reg .= "+1";
+ }
+ }
+
+ if (!defined $reg && $func == 0) {
+ $reg = $registers{'generic'}{0}{$addr};
+ }
+
+ for $i (@{$registers{$card}{$func}{windows}}) {
+ if (defined $data) {
+ # Snoop on data.
+ foreach $j (@{$i->{page}}) {
+ if ($addr == $j->{reg}) {
+ $j->{val} = $data;
+ }
+ }
+ }
+ if ($addr >= $i->{start} && $addr < $i->{end}) {
+ $reg = $i->{pfunc}->($addr, $i->{page});
+ }
+ }
+
+ if (defined $reg) {
+ print " $reg";
+ }
+}
+
+sub print_decoded_int_event($$)
+{
+ my ($text, $funcs) = @_;
+
+ print "$text:";
+
+ for (my $f = 0; $f < 8; $f++) {
+ if ($funcs & (1 << $f)) {
+ printf(" F%d", $f);
+ }
+ }
+ if ($funcs & (1 << 8)) {
+ printf(" UIF");
+ }
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tools/sdio-reinsert.c b/unifi_hostsw_linux_147/sdioemb/tools/sdio-reinsert.c
new file mode 100644
index 0000000..ae246ed
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tools/sdio-reinsert.c
@@ -0,0 +1,32 @@
+/*
+ * Utility for force an SDIO card reinsert.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sdioemb/libsdio.h>
+
+int main(int argc, char *argv[])
+{
+ sdio_uif_t sdev;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <sdio device>\n", argv[0]);
+ exit(1);
+ }
+
+ sdev = sdio_open(argv[1], NULL, NULL);
+ if (!sdev) {
+ perror("sdio_open");
+ exit(1);
+ }
+
+ sdio_reinsert_card(sdev);
+
+ return 0;
+}
diff --git a/unifi_hostsw_linux_147/sdioemb/tools/sdio-set-bus-width.c b/unifi_hostsw_linux_147/sdioemb/tools/sdio-set-bus-width.c
new file mode 100644
index 0000000..9950ac1
--- /dev/null
+++ b/unifi_hostsw_linux_147/sdioemb/tools/sdio-set-bus-width.c
@@ -0,0 +1,38 @@
+/*
+ * Utility to set the SD bus width to 1 or 4 bits.
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sdioemb/libsdio.h>
+
+int main(int argc, char *argv[])
+{
+ sdio_uif_t sdev;
+ int width;
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s <sdio device> <bus width>\n", argv[0]);
+ exit(1);
+ }
+
+ sdev = sdio_open(argv[1], NULL, NULL);
+ if (!sdev) {
+ perror("sdio_open");
+ exit(1);
+ }
+
+ width = atoi(argv[2]);
+ if (width != 1 && width != 4) {
+ fprintf(stderr, "%s: bus width must be 1 or 4\n", argv[0]);
+ exit(1);
+ }
+ sdio_set_bus_width(sdev, width);
+
+ return 0;
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/INSTALL.fc b/unifi_hostsw_linux_147/unifi-linux/INSTALL.fc
new file mode 100644
index 0000000..6121bbf
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/INSTALL.fc
@@ -0,0 +1,104 @@
+
+These instructions describe how to build and install the CSR UniFi linux
+driver on a Fedora Core 5 or 6 system.
+
+
+Prerequisites
+-------------
+The kernel-devel and C development RPMs must be installed.
+For WPA/WPA2 support, kernel version 2.6.14 or newer and wireless-tools
+version 28 or newer are required.
+
+
+Preparation
+-----------
+Untar the driver package into a working directory and cd to the
+top of the driver tree.
+
+
+Building and Installation
+-------------------------
+Run, as root:
+
+ ./fcinstall
+
+When prompted for a Medium Access Control (MAC) address for UniFi,
+enter: FF:FF:FF:FF:FF:FF
+Note:
+ If your UniFi hardware does not have settings in EEPROM, you can manually
+ enter a suitable MAC address here.
+
+
+Configuration
+-------------
+The UniFi firmware is installed into /lib/firmware/unifi-sdio-0 by the
+fcinstall script. If a ufmib.dat file has been supplied with your hardware,
+copy it to /lib/firmware/unifi-sdio-0.
+
+Use the system-config-network tool (follow menu tree: Desktop ->
+System Settings -> Network) to configure the wireless network parameters:
+
+ Click "New"
+
+ Choose "Wireless connection", click "Forward".
+
+ [ Select Wireless Device form ]
+ Choose "Other Wireless Card", click "Forward".
+
+ [ Select Ethernet Adapter form ]
+ In the "Adapter" selection box, choose "CSR UniFi SDIO",
+ leave "Device" as eth1.
+ Click "Forward".
+
+ [ Configure Wireless Connection form ]
+ Set "Mode" to "Managed".
+ Choose "Network Name (SSID)" to be "Specified".
+ In the "Key" field, enter the WEP key or leave as blank for none.
+ Click "Forward".
+
+ [ Configure Network Settings form ]
+ Set as required for your network.
+ Note: if you tick "Automatically obtain DNS information...", your
+ /etc/resolv.conf file will be overwritten, and you may loose DNS
+ functionality.
+ Click "Forward".
+
+ [ Create Wireless Device ]
+ Click "Apply".
+
+ From the menu bar, select File->Save.
+ From the menu bar, select File->Quit.
+
+The values entered in the system-config-network tool are used to write the file
+/etc/sysconfig/network-scripts/ifcfg-eth1.
+
+ From a command prompt, now run:
+ modprobe eth1
+
+
+Verification of success
+-----------------------
+You can verify that the driver is loaded by running lsmod; you should see
+unifi_sdio listed (among others).
+
+dmesg should show messages such as (N.B. version numbers and dates will vary):
+
+ UniFi SDIO Driver: v5.0 (build:84) Jun 30 2008 17:24:29
+ CSR SME with WEXT support, API version: 0.2
+ Unifi: Using CSR embedded SDIO driver
+
+When you insert a UniFi module, dmesg should show messages such as:
+
+ unifi: card inserted
+ unifi0: unifi0 is eth1
+ unifi0: Initialising UniFi, attempt 1
+ unifi0: Chip ID 0x01
+ unifi0: Chip Version 0x1301
+ unifi0: unifi_sdio_hard_reset succeeded on reseting UniFi
+ unifi0: Chip ID 0x01
+ unifi0: Chip Version 0x1301
+ unifi0: needs firmware
+ unifi0: UniFi f/w protocol version 5.1 (driver 5.1)
+ unifi0: Firmware build 420: 2008-06-26 19:34 bgft_core_sta_rambo_sdio_gcc 42
+ unifi0: UniFi ready
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/LICENSE.txt b/unifi_hostsw_linux_147/unifi-linux/LICENSE.txt
new file mode 100644
index 0000000..364853e
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/LICENSE.txt
@@ -0,0 +1,39 @@
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+Except as contained in this notice, the names of above-listed
+copyright holders and the names of any contributors shall not be used
+in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Alternatively, this software may be distributed under the terms of the
+GNU General Public License ("GPL") version 2 as published
+by the Free Software Foundation.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from this file, or you compile this file
+and link it with other works to produce a work based on this file,
+this file does not by itself cause the resulting work to be covered by
+the GNU General Public License. However the source code for this file
+must still be made available in accordance with section (3) of the GNU
+General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
diff --git a/unifi_hostsw_linux_147/unifi-linux/README b/unifi_hostsw_linux_147/unifi-linux/README
new file mode 100644
index 0000000..29bdf0e
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/README
@@ -0,0 +1,40 @@
+---
+
+UniFi Linux Driver
+Copyright (C) 2005-2008 Cambridge Silicon Radio Ltd.
+Last edited: 13-May-2009
+Driver version: 6.1
+
+---
+
+This is version 6.1 of UniFi driver software for Linux and other
+embedded systems, which is designed to work with the UniFi(tm) family
+of chips.
+
+The software includes a complete Linux driver and firmware for UniFi-1.
+It is not compatible with earlier versions of firmware.
+
+The software is compatible with versions 2.6 of the Linux kernel.
+It provides a reference implementation for a UniFi driver and may be used as
+the basis for developing a driver for other platforms.
+
+For information on installing and using the driver on a Fedora Core 5 or 6
+Linux system, see the INSTALL.fc file and the UniFi Linux User Guide for this
+release at http://www.csrsupport.com.
+
+
+
+This software implements a logical interface derived from the Simplified
+Specification published by the SD Association. The Simplified Specification
+is a subset of the complete SD Specification which is owned by the SD Card
+Association. The information contained in the Simplified Specification is
+presented only as a standard specification for SD Cards and SD
+Host/Ancillary products and is provided "AS-IS" without any representations
+or warranties of any kind. No responsibility is assumed by Cambridge Silicon
+Radio Ltd or the SD Card Association for any damages, any infringements of
+patents or other right of the SD Card Association or any third parties,
+which may result from its use. No license is granted by implication,
+estoppel or otherwise under any patent or other rights of the SD Card
+Association or any third party. Parties wishing to manufacture and sell a
+product which embodies intellectual property owned by the SD Card
+Association should obtain a HALA license from http://www.sdcard.org.
diff --git a/unifi_hostsw_linux_147/unifi-linux/common/driver/conversions.h b/unifi_hostsw_linux_147/unifi-linux/common/driver/conversions.h
new file mode 100644
index 0000000..b5b149d
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/common/driver/conversions.h
@@ -0,0 +1,108 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: conversions.h
+ *
+ * PURPOSE:
+ * This header file provides the macros for converting to and from
+ * wire format.
+ * These macros *MUST* work for little-endian AND big-endian hosts.
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#define SIZEOF_UINT16 2
+#define SIZEOF_UINT32 4
+#define SIZEOF_UINT64 8
+
+#define SIZEOF_SIGNAL_HEADER 6
+#define SIZEOF_DATAREF 4
+
+
+/*
+ * Note ptr must be a (uint8 *).
+ */
+#define UNPACK16(ptr, index) (((ptr)[(index) + 1] << 8) + (ptr)[(index)])
+
+#define UNPACK32(ptr, index) ((ptr[index + 3] << 24) + \
+ (ptr[index + 2] << 16) + \
+ (ptr[index + 1] << 8) + \
+ ptr[index])
+
+#define UNPACK64(ptr, index) (((uint64)ptr[index + 7] << 56) + \
+ ((uint64)ptr[index + 6] << 48) + \
+ ((uint64)ptr[index + 5] << 40) + \
+ ((uint64)ptr[index + 4] << 32) + \
+ ((uint64)ptr[index + 3] << 24) + \
+ ((uint64)ptr[index + 2] << 16) + \
+ ((uint64)ptr[index + 1] << 8) + \
+ (uint64)ptr[index])
+
+#define LE_16(dest, value) do { \
+ (dest)[1] = (uint8)((value >> 8) & 0xFF); \
+ (dest)[0] = (uint8)(value & 0xFF); \
+ } while (0)
+
+#define LE_32(dest, value) do { \
+ (dest)[3] = (uint8)((value >> 24) & 0xFF); \
+ (dest)[2] = (uint8)((value >> 16) & 0xFF); \
+ (dest)[1] = (uint8)((value >> 8) & 0xFF); \
+ (dest)[0] = (uint8)(value & 0xFF); \
+ } while (0)
+
+#define LE_64(dest, value) do { \
+ (dest)[7] = (uint8)((value >> 56) & 0xFF); \
+ (dest)[6] = (uint8)((value >> 48) & 0xFF); \
+ (dest)[5] = (uint8)((value >> 40) & 0xFF); \
+ (dest)[4] = (uint8)((value >> 32) & 0xFF); \
+ (dest)[3] = (uint8)((value >> 24) & 0xFF); \
+ (dest)[2] = (uint8)((value >> 16) & 0xFF); \
+ (dest)[1] = (uint8)((value >> 8) & 0xFF); \
+ (dest)[0] = (uint8)(value & 0xFF); \
+ } while (0)
+
+
+/*
+ * Macro to retrieve the signal ID from a wire-format signal.
+ */
+#define GET_SIGNAL_ID(_buf) UNPACK16((_buf), 0)
+
+/*
+ * Macros to retrieve and set the DATAREF fields in a packed (i.e. wire-format)
+ * HIP signal.
+ */
+#define GET_PACKED_DATAREF_SLOT(_buf, _ref) \
+ UNPACK16((_buf), SIZEOF_SIGNAL_HEADER + ((_ref)*SIZEOF_DATAREF) + 0)
+
+#define GET_PACKED_DATAREF_LEN(_buf, _ref) \
+ UNPACK16((_buf), SIZEOF_SIGNAL_HEADER + ((_ref)*SIZEOF_DATAREF) + 2)
+
+#define SET_PACKED_DATAREF_SLOT(_buf, _ref, _slot) \
+ LE_16((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref)*SIZEOF_DATAREF) + 0, (_slot))
+
+#define SET_PACKED_DATAREF_LEN(_buf, _ref, _len) \
+ LE_16((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref)*SIZEOF_DATAREF) + 2, (_len))
+
+#define GET_PACKED_MA_UNIDATA_STATUS_INDICATION_HOSTTAG(_buf) \
+ UNPACK32((_buf), SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF + 18)
+
+#define SET_PACKED_MA_UNIDATA_STATUS_INDICATION_HOSTTAG(_buf, _hosttag) \
+ LE_32((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF + 18, _hosttag)
+
+#define GET_PACKED_MA_UNIDATA_REQUEST_FRAME_PRIORITY(_buf) \
+ UNPACK16((_buf), SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF + 14)
+
+#define GET_PACKED_MA_UNIDATA_REQUEST_HOSTTAG(_buf) \
+ UNPACK32((_buf), SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF + 18)
+
+#define SET_PACKED_MA_UNIDATA_REQUEST_HOSTTAG(_buf, _hosttag) \
+ LE_32((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF + 18, _hosttag)
+
+int get_packed_struct_size(const uint8 *buf);
+int read_unpack_signal(const uint8 *ptr, CSR_SIGNAL *sig);
+int write_pack(const CSR_SIGNAL *sig, uint8 *ptr, unsigned int *sig_len);
diff --git a/unifi_hostsw_linux_147/unifi-linux/common/driver/signals.h b/unifi_hostsw_linux_147/unifi-linux/common/driver/signals.h
new file mode 100644
index 0000000..a456b1a
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/common/driver/signals.h
@@ -0,0 +1,134 @@
+/*
+ *****************************************************************************
+ *
+ * FILE: signals.h
+ *
+ * PURPOSE:
+ * Header file for the auto-generated code in sigs.h and signals.c.
+ * Sigs.h provides structures defining UniFi signals and signals.c
+ * provides SigGetSize() and SigGetDataRefs().
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ *****************************************************************************
+ */
+#ifndef __SIGNALS_H__
+#define __SIGNALS_H__
+
+#include "driver/unifi_types.h"
+
+typedef uint8 uint24[3];
+#include "sigs.h"
+
+
+
+/****************************************************************************/
+/* INFORMATION ELEMENTS */
+/****************************************************************************/
+
+/* Information Element ID's - shouldn't be in here, but nowhere better yet */
+#define IE_SSID_ID 0
+#define IE_SUPPORTED_RATES_ID 1
+#define IE_FH_PARAM_SET_ID 2
+#define IE_DS_PARAM_SET_ID 3
+#define IE_CF_PARAM_SET_ID 4
+#define IE_TIM_ID 5
+#define IE_IBSS_PARAM_SET_ID 6
+#define IE_COUNTRY_ID 7
+#define IE_HOPPING_PATTERN_PARAMS_ID 8
+#define IE_HOPPING_PATTERN_TABLE_ID 9
+#define IE_REQUEST_ID 10
+#define IE_QBSS_LOAD_ID 11
+#define IE_EDCA_PARAM_SET_ID 12
+#define IE_TRAFFIC_SPEC_ID 13
+#define IE_TRAFFIC_CLASS_ID 14
+#define IE_SCHEDULE_ID 15
+#define IE_CHALLENGE_TEXT_ID 16
+#define IE_POWER_CONSTRAINT_ID 32
+#define IE_POWER_CAPABILITY_ID 33
+#define IE_TPC_REQUEST_ID 34
+#define IE_TPC_REPORT_ID 35
+#define IE_SUPPORTED_CHANNELS_ID 36
+#define IE_CHANNEL_SWITCH_ANNOUNCE_ID 37
+#define IE_MEASUREMENT_REQUEST_ID 38
+#define IE_MEASUREMENT_REPORT_ID 39
+#define IE_QUIET_ID 40
+#define IE_IBSS_DFS_ID 41
+#define IE_ERP_INFO_ID 42
+#define IE_TS_DELAY_ID 43
+#define IE_TCLAS_PROCESSING_ID 44
+#define IE_QOS_CAPABILITY_ID 46
+#define IE_RSN_ID 48
+#define IE_EXTENDED_SUPPORTED_RATES_ID 50
+#define IE_AP_CHANNEL_REPORT_ID 52
+#define IE_RCPI_ID 53
+#define IE_WPA_ID 221
+
+
+/* The maximum number of data references in a signal structure */
+#define UNIFI_MAX_DATA_REFERENCES 2
+
+/* The space to allow for a wire-format signal structure */
+#define UNIFI_PACKED_SIGBUF_SIZE 64
+
+
+/******************************************************************************/
+/* SIGNAL PARAMETER VALUES */
+/******************************************************************************/
+
+/* ifIndex */
+#define UNIFI_IF_2G4 1
+#define UNIFI_IF_5G 2
+
+/* SendProcessId */
+#define HOST_PROC_ID 0xc000
+
+#define SIG_CAP_ESS 0x0001
+#define SIG_CAP_IBSS 0x0002
+#define SIG_CAP_CF_POLLABLE 0x0004
+#define SIG_CAP_CF_POLL_REQUEST 0x0008
+#define SIG_CAP_PRIVACY 0x0010
+#define SIG_CAP_SHORT_PREAMBLE 0x0020
+#define SIG_CAP_DSSSOFDM 0x2000
+
+/******************************************************************************/
+/* FUNCTION DECLARATIONS */
+/******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/******************************************************************************
+ * SigGetNumDataRefs - Retrieve pointers to data-refs from a signal.
+ *
+ * PARAMETERS:
+ * aSignal - Pointer to signal to retrieve the data refs of.
+ * aDataRef - Address of a pointer to the structure that the data refs
+ * pointers will be stored.
+ *
+ * RETURNS:
+ * The number of data-refs in the signal.
+ */
+int SigGetDataRefs(CSR_SIGNAL* aSignal, CSR_DATAREF** aDataRef);
+
+/******************************************************************************
+ * SigGetSize - Retrieve the size (in bytes) of a given signal.
+ *
+ * PARAMETERS:
+ * aSignal - Pointer to signal to retrieve size of.
+ *
+ * RETURNS:
+ * The size (in bytes) of the given signal.
+ */
+int SigGetSize(const CSR_SIGNAL* aSignal);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __SIGNALS_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/common/driver/sigs.h b/unifi_hostsw_linux_147/unifi-linux/common/driver/sigs.h
new file mode 100644
index 0000000..cc21cd9
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/common/driver/sigs.h
@@ -0,0 +1,2230 @@
+/* This is an autogenerated file from hip_dd_l_h_gen.pl */
+
+#ifndef SIGS_H
+#define SIGS_H
+
+typedef int csr_place_holding_type;
+
+typedef enum CSR_ANTENNA_ID
+{
+ CSR_ANTENNA_UNKNOWN = 0x0000,
+ CSR_ANTENNA_1 = 0x0001,
+ CSR_ANTENNA_2 = 0x0002,
+ CSR_ANTENNA_MULTIPLE = 0x00ff
+} CSR_ANTENNA_ID;
+
+typedef uint16 CSR_ASSOCIATION_ID;
+
+typedef enum CSR_AUTHENTICATION_TYPE
+{
+ CSR_OPEN_SYSTEM = 0x0000,
+ CSR_SHARED_KEY = 0x0001,
+ CSR_FAST_BSS_TRANSITION = 0x0002
+} CSR_AUTHENTICATION_TYPE;
+
+typedef uint16 CSR_AUTONOMOUS_SCAN_ID;
+
+typedef enum CSR_BSS_TYPE
+{
+ CSR_INFRASTRUCTURE = 0x0000,
+ CSR_INDEPENDENT = 0x0001,
+ CSR_ANY_BSS = 0x0002
+} CSR_BSS_TYPE;
+
+typedef uint16 CSR_BEACON_PERIODS;
+
+typedef enum CSR_BLOCK_ACK_POLICY
+{
+ CSR_DELAYED = 0x0000,
+ CSR_IMMEDIATE = 0x0001
+} CSR_BLOCK_ACK_POLICY;
+
+typedef enum CSR_BOOT_LOADER_OPERATION
+{
+ CSR_BOOT_LOADER_IDLE = 0x00,
+ CSR_BOOT_LOADER_RESTART = 0x01,
+ CSR_BOOT_LOADER_PATCH = 0x02,
+ CSR_BOOT_LOADER_IMAGE_0 = 0x10,
+ CSR_BOOT_LOADER_IMAGE_1 = 0x11,
+ CSR_BOOT_LOADER_IMAGE_2 = 0x12,
+ CSR_BOOT_LOADER_IMAGE_3 = 0x13
+} CSR_BOOT_LOADER_OPERATION;
+
+typedef uint16 CSR_CAPABILITY_INFORMATION;
+
+typedef enum CSR_CHANNEL_OFFSET
+{
+ CSR_SCN = 0x0000,
+ CSR_SCA = 0x0001,
+ CSR_SCB = 0x0003
+} CSR_CHANNEL_OFFSET;
+
+typedef uint16 CSR_CHANNEL_STARTING_FACTOR;
+
+typedef enum CSR_CHANNEL_SWITCH_MODE
+{
+ CSR_CONTINUE = 0x0000,
+ CSR_PAUSE_UNTIL_SWITCH = 0x0001
+} CSR_CHANNEL_SWITCH_MODE;
+
+typedef uint32 CSR_CIPHER_SUITE_SELECTOR;
+
+typedef uint32 CSR_CLIENT_TAG;
+
+typedef enum CSR_COEXISTENCE_DIRECTION
+{
+ CSR_COEXISTENCE_NONE = 0x0000,
+ CSR_COEXISTENCE_DOT11_INPUT = 0x0001,
+ CSR_COEXISTENCE_DOT11_OUTPUT = 0x0002
+} CSR_COEXISTENCE_DIRECTION;
+
+typedef enum CSR_CONNECTION_STATUS
+{
+ CSR_DISCONNECTED = 0x0000,
+ CSR_CONNECTED = 0x0001
+} CSR_CONNECTION_STATUS;
+
+typedef int16 CSR_DECIBELS;
+
+typedef int32 CSR_HERTZ_DELTA;
+
+typedef uint32 CSR_IPV4_ADDRESS;
+
+typedef enum CSR_INITIATOR
+{
+ CSR_RECIPIENT = 0x0000,
+ CSR_ORIGINATOR = 0x0001
+} CSR_INITIATOR;
+
+typedef enum CSR_IFINTERFACE
+{
+ CSR_INDEX_2G4 = 0x0001,
+ CSR_INDEX_5G = 0x0002
+} CSR_IFINTERFACE;
+
+typedef enum CSR_KEY_TYPE
+{
+ CSR_GROUP = 0x0000,
+ CSR_PAIRWISE = 0x0001,
+ CSR_STAKEY = 0x0002,
+ CSR_IGTK = 0x0003
+} CSR_KEY_TYPE;
+
+typedef enum CSR_LINK_MARGIN_CATEGORY
+{
+ CSR_ULM = 0x0001,
+ CSR_DLM = 0x0002,
+ CSR_ALL = 0xffff
+} CSR_LINK_MARGIN_CATEGORY;
+
+typedef enum CSR_LOADER_OPERATION
+{
+ CSR_LOADER_IDLE = 0x0000,
+ CSR_LOADER_COPY = 0x0001
+} CSR_LOADER_OPERATION;
+
+typedef struct CSR_MAC_ADDRESS
+{
+ uint8 x[6];
+} CSR_MACADDRESS;
+
+typedef enum CSR_MIB_STATUS
+{
+ CSR_MIB_SUCCESSFUL = 0x0000,
+ CSR_MIB_INVALID_PARAMETERS = 0x0001,
+ CSR_MIB_WRITE_ONLY = 0x0002,
+ CSR_MIB_READ_ONLY = 0x0003
+} CSR_MIB_STATUS;
+
+typedef enum CSR_MEASUREMENT_CATEGORY
+{
+ CSR_MC_SPECTRUM_MANAGEMENT = 0x0000,
+ CSR_MC_RADIO_MEASUREMENT = 0x0005,
+ CSR_MC_CCX_MEASUREMENT = 0x0006
+} CSR_MEASUREMENT_CATEGORY;
+
+typedef uint16 CSR_MEGAHERTZ;
+
+typedef enum CSR_MEMORY_SPACE
+{
+ CSR_NONE = 0x00,
+ CSR_SHARED_DATA_MEMORY = 0x01,
+ CSR_EXTERNAL_FLASH_MEMORY = 0x02,
+ CSR_EXTERNAL_SRAM = 0x03,
+ CSR_REGISTERS = 0x04,
+ CSR_PHY_PROCESSOR_DATA_MEMORY = 0x10,
+ CSR_PHY_PROCESSOR_PROGRAM_MEMORY = 0x11,
+ CSR_PHY_PROCESSOR_ROM = 0x12,
+ CSR_MAC_PROCESSOR_DATA_MEMORY = 0x20,
+ CSR_MAC_PROCESSOR_PROGRAM_MEMORY = 0x21,
+ CSR_MAC_PROCESSOR_ROM = 0x22,
+ CSR_BT_PROCESSOR_DATA_MEMORY = 0x30,
+ CSR_BT_PROCESSOR_PROGRAM_MEMORY = 0x31,
+ CSR_BT_PROCESSOR_ROM = 0x32
+} CSR_MEMORY_SPACE;
+
+typedef uint16 CSR_MICROSECONDS16;
+
+typedef uint32 CSR_MICROSECONDS32;
+
+typedef uint16 CSR_NATURAL16;
+
+typedef uint32 CSR_NATURAL32;
+
+typedef enum CSR_NEIGHBOR_REPORT_REQUEST_TYPE
+{
+ CSR_NRRT_BASIC = 0x0000,
+ CSR_NRRT_TBTT_OFFSET = 0x0001
+} CSR_NEIGHBOR_REPORT_REQUEST_TYPE;
+
+typedef uint32 CSR_PCI_POINTER;
+
+typedef uint16 CSR_PERIODIC_ID;
+
+typedef enum CSR_PERIODIC_SCHEDULING_MODE
+{
+ CSR_PSM_PERIODIC_SCHEDULE_NONE = 0x0000,
+ CSR_PSM_PERIODIC_SCHEDULE_PS_POLL = 0x0001,
+ CSR_PSM_PERIODIC_SCHEDULE_PM_BIT = 0x0002,
+ CSR_PSM_PERIODIC_SCHEDULE_UAPSD = 0x0004,
+ CSR_PSM_PERIODIC_SCHEDULE_SAPSD = 0x0008,
+ CSR_PSM_PERIODIC_SCHEDULE_CTS = 0x0010
+} CSR_PERIODIC_SCHEDULING_MODE;
+
+typedef enum CSR_POWER_MANAGEMENT_MODE
+{
+ CSR_PMM_ACTIVE_MODE = 0x0000,
+ CSR_PMM_POWER_SAVE = 0x0001,
+ CSR_PMM_FAST_POWER_SAVE = 0x0002
+} CSR_POWER_MANAGEMENT_MODE;
+
+typedef enum CSR_PRIORITY
+{
+ CSR_QOS_UP0 = 0x0000,
+ CSR_QOS_UP1 = 0x0001,
+ CSR_QOS_UP2 = 0x0002,
+ CSR_QOS_UP3 = 0x0003,
+ CSR_QOS_UP4 = 0x0004,
+ CSR_QOS_UP5 = 0x0005,
+ CSR_QOS_UP6 = 0x0006,
+ CSR_QOS_UP7 = 0x0007,
+ CSR_QOS_TSID0 = 0x0008,
+ CSR_QOS_TSID1 = 0x0009,
+ CSR_QOS_TSID2 = 0x000a,
+ CSR_QOS_TSID3 = 0x000b,
+ CSR_QOS_TSID4 = 0x000c,
+ CSR_QOS_TSID5 = 0x000d,
+ CSR_QOS_TSID6 = 0x000e,
+ CSR_QOS_TSID7 = 0x000f,
+ CSR_CONTENTION = 0x8000,
+ CSR_CONTENTION_FREE = 0x8001
+} CSR_PRIORITY;
+
+typedef enum CSR_PROTECT_TYPE
+{
+ CSR_PT_NONE = 0x0000,
+ CSR_PT_RX = 0x0001,
+ CSR_PT_TX = 0x0002,
+ CSR_PT_RX_TX = 0x0003,
+ CSR_PT_RX_MMPDU = 0x0004,
+ CSR_PT_TX_MMPDU = 0x0005,
+ CSR_PT_RX_TX_MMPDU = 0x0006
+} CSR_PROTECT_TYPE;
+
+typedef enum CSR_REASON_CODE
+{
+ CSR_UNSPECIFIED_REASON = 0x0001,
+ CSR_AUTHENTICATION_NOT_VALID = 0x0002,
+ CSR_DEAUTHENTICATED_LEAVE_BSS = 0x0003,
+ CSR_DISASSOCIATED_INACTIVITY = 0x0004,
+ CSR_AP_OVERLOAD = 0x0005,
+ CSR_CLASS2_FRAME_ERROR = 0x0006,
+ CSR_CLASS3_FRAME_ERROR = 0x0007,
+ CSR_DISASSOCIATED_LEAVE_BSS = 0x0008,
+ CSR_ASSOCIATION_NOT_AUTHENTICATED = 0x0009,
+ CSR_DISASSOCIATED_POWER_CAPABILITY = 0x000a,
+ CSR_DISASSOCIATED_SUPPORTED_CHANNELS = 0x000b,
+ CSR_INVALID_INFORMATION_ELEMENT = 0x000d,
+ CSR_MICHAEL_MIC_FAILURE = 0x000e,
+ CSR_FOURWAY_HANDSHAKE_TIMEOUT = 0x000f,
+ CSR_GROUP_KEY_UPDATE_TIMEOUT = 0x0010,
+ CSR_HANDSHAKE_ELEMENT_DIFFERENT = 0x0011,
+ CSR_INVALID_GROUP_CIPHER = 0x0012,
+ CSR_INVALID_PAIRWISE_CIPHER = 0x0013,
+ CSR_INVALID_AKMP = 0x0014,
+ CSR_UNSUPPORTED_RSN_IE_VERSION = 0x0015,
+ CSR_INVALID_RSN_IE_CAPABILITIES = 0x0016,
+ CSR_DOT1X_AUTH_FAILED = 0x0017,
+ CSR_CIPHER_REJECTED_BY_POLICY = 0x0018,
+ CSR_SERVICE_CHANGE_PRECLUDES_TS = 0x001F,
+ CSR_QOS_UNSPECIFIED_REASON = 0x0020,
+ CSR_QOS_INSUFFICIENT_BANDWIDTH = 0x0021,
+ CSR_QOS_EXCESSIVE_NOT_ACK = 0x0022,
+ CSR_QOS_TXOP_LIMIT_EXCEEDED = 0x0023,
+ CSR_QSTA_LEAVING = 0x0024,
+ CSR_END_BA = 0x0025,
+ CSR_END_DLS = 0x0025,
+ CSR_END_TS = 0x0025,
+ CSR_UNKNOWN_DLS = 0x0026,
+ CSR_UNKNOWN_BA = 0x0026,
+ CSR_UNKNOWN_TS = 0x0026,
+ CSR_TIMEOUT = 0x0027,
+ CSR_STAKEY_MISMATCH = 0x002d
+} CSR_REASON_CODE;
+
+typedef uint64 CSR_RECEIVE_SEQUENCE_COUNT;
+
+typedef enum CSR_RECEPTION_STATUS
+{
+ CSR_RX_SUCCESS = 0x0000,
+ CSR_RX_FAILURE = 0x0001
+} CSR_RECEPTION_STATUS;
+
+typedef enum CSR_RESULT_CODE
+{
+ CSR_RC_SUCCESS = 0x0000,
+ CSR_RC_UNSPECIFIED_FAILURE = 0x0001,
+ CSR_RC_REFUSED_CAPABILITIES_MISMATCH = 0x000a,
+ CSR_RC_REASSOCIATION_DENIED_NO_ASSOCIATION = 0x000b,
+ CSR_RC_REFUSED_EXTERNAL_REASON = 0x000c,
+ CSR_RC_REFUSED_AUTHENTICATION_MISMATCH = 0x000d,
+ CSR_RC_REFUSED_INVALID_AUTHENTICATION_SEQUENCE_NUMBER= 0x000e,
+ CSR_RC_REFUSED_CHALLENGE_FAILURE = 0x000f,
+ CSR_RC_REFUSED_AUTHENTICATION_TIMEOUT = 0x0010,
+ CSR_RC_REFUSED_AP_OUT_OF_MEMORY = 0x0011,
+ CSR_RC_REFUSED_BASIC_RATES_MISMATCH = 0x0012,
+ CSR_RC_REFUSED_SHORT_PREAMBLE_REQUIRED = 0x0013,
+ CSR_RC_REFUSED_PBCC_MODULATION_REQUIRED = 0x0014,
+ CSR_RC_REFUSED_CHANNEL_AGILITY_REQUIRED = 0x0015,
+ CSR_RC_REFUSED_SPECTRUM_MANAGEMENT_REQUIRED = 0x0016,
+ CSR_RC_REFUSED_POWER_CAPABILITY_UNACCEPTABLE = 0x0017,
+ CSR_RC_REFUSED_SUPPORTED_CHANNELS_UNACCEPTABLE= 0x0018,
+ CSR_RC_REFUSED_SHORT_SLOT_REQUIRED = 0x0019,
+ CSR_RC_REFUSED_DSSS_OFDM_REQUIRED = 0x001a,
+ CSR_RC_REFUSED_NO_HT_SUPPORT = 0x001b,
+ CSR_RC_R0KH_UNREACHABLE = 0x001c,
+ CSR_RC_REFUSED_PCO_TRANSITION_SUPPORT = 0x001d,
+ CSR_RC_FAILURE = 0x0020,
+ CSR_RC_REFUSED_AP_BANDWIDTH_INSUFFICIENT = 0x0021,
+ CSR_RC_REFUSED_POOR_OPERATING_CHANNEL = 0x0022,
+ CSR_RC_REFUSED_QOS_REQUIRED = 0x0023,
+ CSR_RC_REFUSED = 0x0025,
+ CSR_RC_REFUSED_REASON_UNSPECIFIED = 0x0025,
+ CSR_RC_INVALID_PARAMETERS = 0x0026,
+ CSR_RC_REJECTED_WITH_SUGGESTED_TSPEC_CHANGES = 0x0027,
+ CSR_RC_REJECTED_INVALID_IE = 0x0028,
+ CSR_RC_REJECTED_INVALID_GROUP_CIPHER = 0x0029,
+ CSR_RC_REJECTED_INVALID_PAIRWISE_CIPHER = 0x002a,
+ CSR_RC_REJECTED_INVALID_AKMP = 0x002b,
+ CSR_RC_REJECTED_UNSUPPORTED_RSN_VERSION = 0x002c,
+ CSR_RC_REJECTED_INVALID_RSN_CAPABILITY = 0x002d,
+ CSR_RC_REJECTED_SECURITY_POLICY = 0x002e,
+ CSR_RC_REJECTED_FOR_DELAY_PERIOD = 0x002f,
+ CSR_RC_NOT_ALLOWED = 0x0030,
+ CSR_RC_NOT_PRESENT = 0x0031,
+ CSR_RC_NOT_QSTA = 0x0032,
+ CSR_RC_REJECTED_LISTENINTERVAL_TOO_LARGE = 0x0033,
+ CSR_RC_INVALID_FT_ACTION_FRAME_COUNT = 0x0034,
+ CSR_RC_INVALID_PMKID = 0x0035,
+ CSR_RC_INVALID_MDIE = 0x0036,
+ CSR_RC_INVALID_FTIE = 0x0037,
+ CSR_RC_UNSPECIFIED_QOS_FAILURE = 0x00c8,
+ CSR_RC_WRONG_POLICY = 0x00c9,
+ CSR_RC_INSUFFICIENT_BANDWIDTH = 0x00ca,
+ CSR_RC_INVALID_TSPEC_PARAMETERS = 0x00cb,
+ CSR_RC_TIMEOUT = 0x8000,
+ CSR_RC_TOO_MANY_SIMULTANEOUS_REQUESTS = 0x8001,
+ CSR_RC_BSS_ALREADY_STARTED_OR_JOINED = 0x8002,
+ CSR_RC_NOT_SUPPORTED = 0x8003,
+ CSR_RC_TRANSMISSION_FAILURE = 0x8004,
+ CSR_RC_REFUSED_NOT_AUTHENTICATED = 0x8005,
+ CSR_RC_RESET_REQUIRED_BEFORE_START = 0x8006,
+ CSR_RC_LM_INFO_UNAVAILABLE = 0x8007
+} CSR_RESULT_CODE;
+
+typedef enum CSR_ROUTING_INFORMATION
+{
+ CSR_NULL_RT = 0x0000
+} CSR_ROUTING_INFORMATION;
+
+typedef enum CSR_SCAN_TYPE
+{
+ CSR_SC_ACTIVE_SCAN = 0x0000,
+ CSR_SC_PASSIVE_SCAN = 0x0001
+} CSR_SCAN_TYPE;
+
+typedef uint16 CSR_SECONDS;
+
+typedef enum CSR_SERVICE_CLASS
+{
+ CSR_REORDERABLE_MULTICAST = 0x0000,
+ CSR_STRICTLY_ORDERED = 0x0001,
+ CSR_QOS_ACK = 0x0002,
+ CSR_QOS_NO_ACK = 0x0003,
+ CSR_QOS_LOCAL_MULTICAST = 0x0004
+} CSR_SERVICE_CLASS;
+
+typedef enum CSR_SIGNAL_ID
+{
+ CSR_MA_UNITDATA_REQUEST_ID = 0x0100,
+ CSR_MA_UNITDATA_CONFIRM_ID = 0x0101,
+ CSR_MA_UNITDATA_INDICATION_ID = 0x0103,
+ CSR_MA_UNITDATA_STATUS_INDICATION_DEPRECATED_ID= 0x0107,
+ CSR_MA_SNIFFDATA_INDICATION_ID = 0x010b,
+ CSR_MA_UNITDATA_CANCEL_REQUEST_ID = 0x010c,
+ CSR_MLME_RESET_REQUEST_ID = 0x0200,
+ CSR_MLME_RESET_CONFIRM_ID = 0x0201,
+ CSR_MLME_GET_REQUEST_ID = 0x0204,
+ CSR_MLME_GET_CONFIRM_ID = 0x0205,
+ CSR_MLME_SET_REQUEST_ID = 0x0208,
+ CSR_MLME_SET_CONFIRM_ID = 0x0209,
+ CSR_MLME_GET_NEXT_REQUEST_ID = 0x020c,
+ CSR_MLME_GET_NEXT_CONFIRM_ID = 0x020d,
+ CSR_MLME_POWERMGT_REQUEST_ID = 0x0210,
+ CSR_MLME_POWERMGT_CONFIRM_ID = 0x0211,
+ CSR_MLME_SCAN_REQUEST_ID = 0x0214,
+ CSR_MLME_SCAN_CONFIRM_ID = 0x0215,
+ CSR_MLME_SCAN_INDICATION_ID = 0x0217,
+ CSR_MLME_JOIN_REQUEST_ID = 0x0218,
+ CSR_MLME_JOIN_CONFIRM_ID = 0x0219,
+ CSR_MLME_AUTHENTICATE_REQUEST_ID = 0x021c,
+ CSR_MLME_AUTHENTICATE_CONFIRM_ID = 0x021d,
+ CSR_MLME_AUTHENTICATE_RESPONSE_ID = 0x021e,
+ CSR_MLME_AUTHENTICATE_INDICATION_ID = 0x021f,
+ CSR_MLME_DEAUTHENTICATE_REQUEST_ID = 0x0220,
+ CSR_MLME_DEAUTHENTICATE_CONFIRM_ID = 0x0221,
+ CSR_MLME_DEAUTHENTICATE_INDICATION_ID = 0x0223,
+ CSR_MLME_ASSOCIATE_REQUEST_ID = 0x0224,
+ CSR_MLME_ASSOCIATE_CONFIRM_ID = 0x0225,
+ CSR_MLME_ASSOCIATE_RESPONSE_ID = 0x0226,
+ CSR_MLME_ASSOCIATE_INDICATION_ID = 0x0227,
+ CSR_MLME_REASSOCIATE_REQUEST_ID = 0x0228,
+ CSR_MLME_REASSOCIATE_CONFIRM_ID = 0x0229,
+ CSR_MLME_REASSOCIATE_RESPONSE_ID = 0x022a,
+ CSR_MLME_REASSOCIATE_INDICATION_ID = 0x022b,
+ CSR_MLME_DISASSOCIATE_REQUEST_ID = 0x022c,
+ CSR_MLME_DISASSOCIATE_CONFIRM_ID = 0x022d,
+ CSR_MLME_DISASSOCIATE_INDICATION_ID = 0x022f,
+ CSR_MLME_START_REQUEST_ID = 0x0230,
+ CSR_MLME_START_CONFIRM_ID = 0x0231,
+ CSR_MLME_ADDTS_REQUEST_ID = 0x0234,
+ CSR_MLME_ADDTS_CONFIRM_ID = 0x0235,
+ CSR_MLME_ADDTS_RESPONSE_ID = 0x0236,
+ CSR_MLME_ADDTS_INDICATION_ID = 0x0237,
+ CSR_MLME_DELTS_REQUEST_ID = 0x0238,
+ CSR_MLME_DELTS_CONFIRM_ID = 0x0239,
+ CSR_MLME_DELTS_INDICATION_ID = 0x023b,
+ CSR_MLME_DLS_REQUEST_ID = 0x023c,
+ CSR_MLME_DLS_CONFIRM_ID = 0x023d,
+ CSR_MLME_DLS_INDICATION_ID = 0x023f,
+ CSR_MLME_DLSTEARDOWN_REQUEST_ID = 0x0240,
+ CSR_MLME_DLSTEARDOWN_CONFIRM_ID = 0x0241,
+ CSR_MLME_DLSTEARDOWN_INDICATION_ID = 0x0243,
+ CSR_MLME_HL_SYNC_REQUEST_ID = 0x0244,
+ CSR_MLME_HL_SYNC_CONFIRM_ID = 0x0245,
+ CSR_MLME_HL_SYNC_INDICATION_ID = 0x0247,
+ CSR_MLME_ADDBA_REQUEST_ID = 0x0248,
+ CSR_MLME_ADDBA_CONFIRM_ID = 0x0249,
+ CSR_MLME_ADDBA_RESPONSE_ID = 0x024a,
+ CSR_MLME_ADDBA_INDICATION_ID = 0x024b,
+ CSR_MLME_DELBA_REQUEST_ID = 0x024c,
+ CSR_MLME_DELBA_CONFIRM_ID = 0x024d,
+ CSR_MLME_DELBA_INDICATION_ID = 0x024f,
+ CSR_MLME_SCHEDULE_REQUEST_ID = 0x0250,
+ CSR_MLME_SCHEDULE_CONFIRM_ID = 0x0251,
+ CSR_MLME_SCHEDULE_INDICATION_ID = 0x0253,
+ CSR_MLME_MREQUEST_REQUEST_ID = 0x0254,
+ CSR_MLME_MREQUEST_CONFIRM_ID = 0x0255,
+ CSR_MLME_MREQUEST_INDICATION_ID = 0x0257,
+ CSR_MLME_MEASURE_REQUEST_ID = 0x0258,
+ CSR_MLME_MEASURE_CONFIRM_ID = 0x0259,
+ CSR_MLME_MREPORT_REQUEST_ID = 0x025c,
+ CSR_MLME_MREPORT_CONFIRM_ID = 0x025d,
+ CSR_MLME_MREPORT_INDICATION_ID = 0x025f,
+ CSR_MLME_CHANNELSWITCH_REQUEST_ID = 0x0260,
+ CSR_MLME_CHANNELSWITCH_CONFIRM_ID = 0x0261,
+ CSR_MLME_CHANNELSWITCH_RESPONSE_ID = 0x0262,
+ CSR_MLME_CHANNELSWITCH_INDICATION_ID = 0x0263,
+ CSR_MLME_TPCADAPT_REQUEST_ID = 0x0264,
+ CSR_MLME_TPCADAPT_CONFIRM_ID = 0x0265,
+ CSR_MLME_SETKEYS_REQUEST_ID = 0x0268,
+ CSR_MLME_SETKEYS_CONFIRM_ID = 0x0269,
+ CSR_MLME_DELETEKEYS_REQUEST_ID = 0x026c,
+ CSR_MLME_DELETEKEYS_CONFIRM_ID = 0x026d,
+ CSR_MLME_MICHAELMICFAILURE_INDICATION_ID = 0x0273,
+ CSR_MLME_EAPOL_REQUEST_ID = 0x0274,
+ CSR_MLME_EAPOL_CONFIRM_ID = 0x0275,
+ CSR_MLME_STAKEYESTABLISHED_INDICATION_ID = 0x027b,
+ CSR_MLME_SETPROTECTION_REQUEST_ID = 0x027c,
+ CSR_MLME_SETPROTECTION_CONFIRM_ID = 0x027d,
+ CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID = 0x0283,
+ CSR_MLME_SNIFFJOIN_REQUEST_ID = 0x0284,
+ CSR_MLME_SNIFFJOIN_CONFIRM_ID = 0x0285,
+ CSR_MLME_CONNECTED_INDICATION_ID = 0x028b,
+ CSR_MLME_SCAN_CANCEL_REQUEST_ID = 0x028c,
+ CSR_MLME_LINKMEASURE_REQUEST_ID = 0x0294,
+ CSR_MLME_LINKMEASURE_CONFIRM_ID = 0x0295,
+ CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID = 0x0298,
+ CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID = 0x0299,
+ CSR_MLME_ADD_PERIODIC_REQUEST_ID = 0x02a0,
+ CSR_MLME_ADD_PERIODIC_CONFIRM_ID = 0x02a1,
+ CSR_MLME_DEL_PERIODIC_REQUEST_ID = 0x02a4,
+ CSR_MLME_DEL_PERIODIC_CONFIRM_ID = 0x02a5,
+ CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID = 0x02a8,
+ CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID = 0x02a9,
+ CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID = 0x02ac,
+ CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID = 0x02ad,
+ CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID = 0x02b3,
+ CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID = 0x02b4,
+ CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID = 0x02b5,
+ CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID= 0x02b7,
+ CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID = 0x02b8,
+ CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID = 0x02b9,
+ CSR_MLME_FT_JOIN_REQUEST_ID = 0x02bc,
+ CSR_MLME_FT_JOIN_CONFIRM_ID = 0x02bd,
+ CSR_MLME_RESOURCE_REQUEST_REQUEST_ID = 0x02c0,
+ CSR_MLME_RESOURCE_REQUEST_CONFIRM_ID = 0x02c1,
+ CSR_MLME_RESOURCE_REQUEST_RESPONSE_ID = 0x02c2,
+ CSR_MLME_RESOURCE_REQUEST_INDICATION_ID = 0x02c3,
+ CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST_ID = 0x02c4,
+ CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM_ID = 0x02c5,
+ CSR_MLME_REMOTE_REQUEST_REQUEST_ID = 0x02c8,
+ CSR_MLME_REMOTE_REQUEST_CONFIRM_ID = 0x02c9,
+ CSR_MLME_REMOTE_REQUEST_INDICATION_ID = 0x02cb,
+ CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID = 0x02cc,
+ CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID = 0x02cd,
+ CSR_MLME_NEIGHBORREPREQ_REQUEST_ID = 0x02d0,
+ CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID = 0x02d1,
+ CSR_MLME_NEIGHBORREPREQ_INDICATION_ID = 0x02d3,
+ CSR_MLME_NEIGHBORREPRESP_REQUEST_ID = 0x02d4,
+ CSR_MLME_NEIGHBORREPRESP_CONFIRM_ID = 0x02d5,
+ CSR_MLME_NEIGHBORREPRESP_INDICATION_ID = 0x02d7,
+ CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID = 0x02db,
+ CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID = 0x02dc,
+ CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID = 0x02dd,
+ CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID = 0x02e0,
+ CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID = 0x02e1,
+ CSR_MLME_TRIGGERED_GET_INDICATION_ID = 0x02e7,
+ CSR_MLME_PING_REQUEST_ID = 0x02e8,
+ CSR_MLME_PING_CONFIRM_ID = 0x02e9,
+ CSR_MLME_PING_RESPONSE_ID = 0x02ea,
+ CSR_MLME_PING_INDICATION_ID = 0x02eb,
+ CSR_MLME_VSPECIFIC_REQUEST_ID = 0x02ec,
+ CSR_MLME_VSPECIFIC_CONFIRM_ID = 0x02ed,
+ CSR_MLME_VSPECIFIC_INDICATION_ID = 0x02ef,
+ CSR_MLME_ADD_WDS_REQUEST_ID = 0x02f0,
+ CSR_MLME_ADD_WDS_CONFIRM_ID = 0x02f1,
+ CSR_MLME_DEL_WDS_REQUEST_ID = 0x02f4,
+ CSR_MLME_DEL_WDS_CONFIRM_ID = 0x02f5,
+ CSR_DS_UNITDATA_REQUEST_ID = 0x0400,
+ CSR_DS_UNITDATA_RESPONSE_ID = 0x0402,
+ CSR_DS_UNITDATA_INDICATION_ID = 0x0403,
+ CSR_DS_UNITDATA_CANCEL_INDICATION_ID = 0x0407,
+ CSR_DS_STA_NOTIFY_REQUEST_ID = 0x0408,
+ CSR_DEBUG_STRING_INDICATION_ID = 0x0803,
+ CSR_DEBUG_WORD16_INDICATION_ID = 0x0807,
+ CSR_DEBUG_GENERIC_REQUEST_ID = 0x0808,
+ CSR_DEBUG_GENERIC_CONFIRM_ID = 0x0809,
+ CSR_DEBUG_GENERIC_INDICATION_ID = 0x080b
+} CSR_SIGNAL_ID;
+
+typedef uint16 CSR_SIMPLE_POINTER;
+
+typedef enum CSR_SNIFFER_RECEPTION_STATUS
+{
+ CSR_SNIFF_SUCCESS = 0x0000,
+ CSR_SNIFF_UNSUPPORTED_MODULATION = 0x0001,
+ CSR_SNIFF_BAD_FCS = 0x0002,
+ CSR_SNIFF_BAD_SIGNAL = 0x0003
+} CSR_SNIFFER_RECEPTION_STATUS;
+
+typedef enum CSR_SOURCE_TYPE
+{
+ CSR_SCR_AP = 0x0000,
+ CSR_SCR_PORTAL = 0x0001
+} CSR_SOURCE_TYPE;
+
+typedef enum CSR_SYMBOL_ID
+{
+ CSR_SLT_END = 0x0000,
+ CSR_SLT_PCI_SLOT_CONFIG = 0x0001,
+ CSR_SLT_SDIO_SLOT_CONFIG = 0x0002,
+ CSR_SLT_BUILD_ID_NUMBER = 0x0003,
+ CSR_SLT_BUILD_ID_STRING = 0x0004,
+ CSR_SLT_PERSISTENT_STORE_DB = 0x0005,
+ CSR_SLT_RESET_VECTOR_PHY = 0x0006,
+ CSR_SLT_RESET_VECTOR_MAC = 0x0007,
+ CSR_SLT_SDIO_LOADER_CONTROL = 0x0008,
+ CSR_SLT_TEST_CMD = 0x0009,
+ CSR_SLT_TEST_ALIVE_COUNTER = 0x000a,
+ CSR_SLT_TEST_PARAMETERS = 0x000b,
+ CSR_SLT_TEST_RESULTS = 0x000c,
+ CSR_SLT_TEST_VERSION = 0x000d,
+ CSR_SLT_MIB_PSID_RANGES = 0x000e,
+ CSR_SLT_KIP_TABLE = 0x000f,
+ CSR_SLT_PANIC_DATA_PHY = 0x0010,
+ CSR_SLT_PANIC_DATA_MAC = 0x0011,
+ CSR_SLT_BOOT_LOADER_CONTROL = 0x0012
+} CSR_SYMBOL_ID;
+
+typedef uint64 CSR_TSF_TIME;
+
+typedef uint16 CSR_TIME_UNITS;
+
+typedef enum CSR_TRANSMISSION_STATUS
+{
+ CSR_TX_SUCCESSFUL = 0x0000,
+ CSR_TX_RETRY_LIMIT = 0x0001,
+ CSR_TX_LIFETIME = 0x0002,
+ CSR_TX_NO_BSS = 0x0003,
+ CSR_TX_EXCESSIVE_DATA_LENGTH = 0x0004,
+ CSR_TX_NON_NULL_SOURCE_ROUTING = 0x0005,
+ CSR_TX_UNSUPPORTED_PRIORITY = 0x0006,
+ CSR_TX_UNAVAILABLE_PRIORITY = 0x0007,
+ CSR_TX_UNSUPPORTED_SERVICE_CLASS = 0x0008,
+ CSR_TX_UNAVAILABLE_SERVICE_CLASS = 0x0009,
+ CSR_TX_UNAVAILABLE_KEY_MAPPING = 0x000a,
+ CSR_TX_EDCA_TIMEOUT = 0x000b,
+ CSR_TX_BLOCK_ACK_TIMEOUT = 0x000c
+} CSR_TRANSMISSION_STATUS;
+
+typedef uint16 CSR_TRIGGERED_ID;
+
+typedef enum CSR_UNIT_DATA_FILTER_MODE
+{
+ CSR_UDFM_OPT_OUT = 0x0000,
+ CSR_UDFM_OPT_IN = 0x0003
+} CSR_UNIT_DATA_FILTER_MODE;
+
+typedef enum CSR_UPDATE_TYPE
+{
+ CSR_ADD = 0x0000,
+ CSR_MOVE = 0x0001,
+ CSR_DELETE = 0x0002
+} CSR_UPDATE_TYPE;
+
+typedef uint16 CSR_BUFFER_HANDLE;
+
+typedef uint16 CSR_CHANNEL_NUMBER;
+
+typedef struct CSR_DATA_REFERENCE
+{
+ uint16 SlotNumber;
+ uint16 DataLength;
+} CSR_DATAREF;
+
+typedef uint16 CSR_DIALOG_TOKEN;
+
+typedef struct CSR_GENERIC_POINTER
+{
+ uint24 MemoryOffset;
+ CSR_MEMORY_SPACE MemorySpace;
+} CSR_GENERIC_POINTER;
+
+typedef struct CSR_MA_UNITDATA_REQUEST
+{
+ CSR_DATAREF Data;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Da;
+ CSR_MACADDRESS Sa;
+ CSR_ROUTING_INFORMATION RoutingInformation;
+ CSR_PRIORITY Priority;
+ CSR_SERVICE_CLASS ServiceClass;
+ CSR_CLIENT_TAG HostTag;
+} CSR_MA_UNITDATA_REQUEST;
+
+typedef struct CSR_MA_UNITDATA_CANCEL_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_CLIENT_TAG HostTag;
+} CSR_MA_UNITDATA_CANCEL_REQUEST;
+
+typedef struct CSR_MLME_ADDBA_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerQstaAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_PRIORITY Tid;
+ CSR_RESULT_CODE ResultCode;
+ CSR_BLOCK_ACK_POLICY BlockAckPolicy;
+ CSR_NATURAL16 BufferSize;
+ CSR_TIME_UNITS BlockAckTimeout;
+} CSR_MLME_ADDBA_CONFIRM;
+
+typedef struct CSR_MLME_ADDBA_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerQstaAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_PRIORITY Tid;
+ CSR_BLOCK_ACK_POLICY BlockAckPolicy;
+ CSR_NATURAL16 BufferSize;
+ CSR_TIME_UNITS BlockAckTimeout;
+} CSR_MLME_ADDBA_INDICATION;
+
+typedef struct CSR_MLME_ADDBA_RESPONSE
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerQstaAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_PRIORITY Tid;
+ CSR_RESULT_CODE ResultCode;
+ CSR_BLOCK_ACK_POLICY BlockAckPolicy;
+ CSR_NATURAL16 BufferSize;
+ CSR_TIME_UNITS BlockAckTimeout;
+} CSR_MLME_ADDBA_RESPONSE;
+
+typedef struct CSR_MLME_ADDTS_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_ADDTS_CONFIRM;
+
+typedef struct CSR_MLME_ADDTS_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_MACADDRESS NonapQstaAddress;
+} CSR_MLME_ADDTS_INDICATION;
+
+typedef struct CSR_MLME_ADDTS_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_TIME_UNITS AddtsFailureTimeout;
+} CSR_MLME_ADDTS_REQUEST;
+
+typedef struct CSR_MLME_ADDTS_RESPONSE
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_MACADDRESS NonapQstaAddress;
+} CSR_MLME_ADDTS_RESPONSE;
+
+typedef struct CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+} CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM;
+
+typedef struct CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST
+{
+ CSR_DATAREF ChannelList;
+ CSR_DATAREF InformationElements;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+ CSR_IFINTERFACE Ifindex;
+ CSR_CHANNEL_STARTING_FACTOR ChannelStartingFactor;
+ CSR_BSS_TYPE BssType;
+ CSR_MACADDRESS Bssid;
+ CSR_SCAN_TYPE ScanType;
+ CSR_MICROSECONDS32 ProbeDelay;
+ CSR_TIME_UNITS MinChannelTime;
+ CSR_TIME_UNITS MaxChannelTime;
+} CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST;
+
+typedef struct CSR_MLME_ADD_PERIODIC_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_PERIODIC_ID PeriodicId;
+} CSR_MLME_ADD_PERIODIC_CONFIRM;
+
+typedef struct CSR_MLME_ADD_PERIODIC_REQUEST
+{
+ CSR_DATAREF DownlinkInformationElements;
+ CSR_DATAREF UplinkInformationElements;
+ CSR_PERIODIC_ID PeriodicId;
+ CSR_COEXISTENCE_DIRECTION CoexistenceDirection;
+ CSR_PERIODIC_SCHEDULING_MODE PeriodicSchedulingMode;
+ int16 WakeHost;
+} CSR_MLME_ADD_PERIODIC_REQUEST;
+
+typedef struct CSR_MLME_ADD_TRIGGERED_GET_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_TRIGGERED_ID TriggeredId;
+} CSR_MLME_ADD_TRIGGERED_GET_CONFIRM;
+
+typedef struct CSR_MLME_ADD_TRIGGERED_GET_REQUEST
+{
+ CSR_DATAREF MibAttribute;
+ CSR_DATAREF Dummydataref2;
+ CSR_TRIGGERED_ID TriggeredId;
+} CSR_MLME_ADD_TRIGGERED_GET_REQUEST;
+
+typedef struct CSR_MLME_ADD_WDS_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_ADD_WDS_CONFIRM;
+
+typedef struct CSR_MLME_ADD_WDS_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS WdsApMacAddress;
+} CSR_MLME_ADD_WDS_REQUEST;
+
+typedef struct CSR_MLME_ASSOCIATE_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_TIME_UNITS AssociateFailureTimeout;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_BEACON_PERIODS ListenInterval;
+} CSR_MLME_ASSOCIATE_REQUEST;
+
+typedef struct CSR_MLME_AUTHENTICATE_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_AUTHENTICATION_TYPE AuthenticationType;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_AUTHENTICATE_CONFIRM;
+
+typedef struct CSR_MLME_AUTHENTICATE_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_AUTHENTICATION_TYPE AuthenticationType;
+} CSR_MLME_AUTHENTICATE_INDICATION;
+
+typedef struct CSR_MLME_AUTHENTICATE_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_AUTHENTICATION_TYPE AuthenticationType;
+ CSR_TIME_UNITS AuthenticationFailureTimeout;
+} CSR_MLME_AUTHENTICATE_REQUEST;
+
+typedef struct CSR_MLME_AUTHENTICATE_RESPONSE
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_AUTHENTICATE_RESPONSE;
+
+typedef struct CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+} CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION;
+
+typedef struct CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+} CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM;
+
+typedef struct CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+ CSR_MACADDRESS Bssid;
+ CSR_CHANNEL_NUMBER Channel;
+ CSR_MEGAHERTZ ChannelFrequency;
+ CSR_DECIBELS Rssi;
+ CSR_DECIBELS Snr;
+} CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION;
+
+typedef struct CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+} CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST;
+
+typedef struct CSR_MLME_CHANNELSWITCH_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_CHANNELSWITCH_CONFIRM;
+
+typedef struct CSR_MLME_CHANNELSWITCH_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_CHANNEL_SWITCH_MODE Mode;
+ CSR_CHANNEL_NUMBER ChannelNumber;
+ CSR_CHANNEL_OFFSET SecondaryChannelOffset;
+ CSR_BEACON_PERIODS ChannelSwitchCount;
+} CSR_MLME_CHANNELSWITCH_INDICATION;
+
+typedef struct CSR_MLME_CHANNELSWITCH_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_CHANNEL_SWITCH_MODE Mode;
+ CSR_CHANNEL_NUMBER ChannelNumber;
+ CSR_CHANNEL_OFFSET SecondaryChannelOffset;
+ CSR_BEACON_PERIODS ChannelSwitchCount;
+} CSR_MLME_CHANNELSWITCH_REQUEST;
+
+typedef struct CSR_MLME_CHANNELSWITCH_RESPONSE
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_CHANNEL_SWITCH_MODE Mode;
+ CSR_CHANNEL_NUMBER ChannelNumber;
+ CSR_CHANNEL_OFFSET SecondaryChannelOffset;
+ CSR_BEACON_PERIODS ChannelSwitchCount;
+} CSR_MLME_CHANNELSWITCH_RESPONSE;
+
+typedef struct CSR_MLME_CONNECTED_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_CONNECTION_STATUS ConnectionStatus;
+ CSR_MACADDRESS PeerMacAddress;
+} CSR_MLME_CONNECTED_INDICATION;
+
+typedef struct CSR_MLME_DEAUTHENTICATE_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_DEAUTHENTICATE_CONFIRM;
+
+typedef struct CSR_MLME_DEAUTHENTICATE_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DEAUTHENTICATE_INDICATION;
+
+typedef struct CSR_MLME_DEAUTHENTICATE_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DEAUTHENTICATE_REQUEST;
+
+typedef struct CSR_MLME_DELBA_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerQstaAddress;
+ CSR_INITIATOR Direction;
+ CSR_PRIORITY Tid;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_DELBA_CONFIRM;
+
+typedef struct CSR_MLME_DELBA_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerQstaAddress;
+ CSR_INITIATOR Direction;
+ CSR_PRIORITY Tid;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DELBA_INDICATION;
+
+typedef struct CSR_MLME_DELBA_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerQstaAddress;
+ CSR_INITIATOR Direction;
+ CSR_PRIORITY Tid;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DELBA_REQUEST;
+
+typedef struct CSR_MLME_DELETEKEYS_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_DELETEKEYS_CONFIRM;
+
+typedef struct CSR_MLME_DELETEKEYS_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_NATURAL16 KeyId;
+ CSR_KEY_TYPE KeyType;
+ CSR_MACADDRESS Address;
+} CSR_MLME_DELETEKEYS_REQUEST;
+
+typedef struct CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+} CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM;
+
+typedef struct CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+} CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST;
+
+typedef struct CSR_MLME_DEL_PERIODIC_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_PERIODIC_ID PeriodicId;
+} CSR_MLME_DEL_PERIODIC_CONFIRM;
+
+typedef struct CSR_MLME_DEL_PERIODIC_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_PERIODIC_ID PeriodicId;
+} CSR_MLME_DEL_PERIODIC_REQUEST;
+
+typedef struct CSR_MLME_DEL_TRIGGERED_GET_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_TRIGGERED_ID TriggeredId;
+} CSR_MLME_DEL_TRIGGERED_GET_CONFIRM;
+
+typedef struct CSR_MLME_DEL_TRIGGERED_GET_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_TRIGGERED_ID TriggeredId;
+} CSR_MLME_DEL_TRIGGERED_GET_REQUEST;
+
+typedef struct CSR_MLME_DEL_WDS_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_DEL_WDS_CONFIRM;
+
+typedef struct CSR_MLME_DEL_WDS_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS WdsApMacAddress;
+} CSR_MLME_DEL_WDS_REQUEST;
+
+typedef struct CSR_MLME_DISASSOCIATE_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_DISASSOCIATE_CONFIRM;
+
+typedef struct CSR_MLME_DISASSOCIATE_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DISASSOCIATE_INDICATION;
+
+typedef struct CSR_MLME_DISASSOCIATE_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DISASSOCIATE_REQUEST;
+
+typedef struct CSR_MLME_DLS_CONFIRM
+{
+ CSR_DATAREF SupportedRates;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_RESULT_CODE ResultCode;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_SECONDS DlsTimeoutValue;
+} CSR_MLME_DLS_CONFIRM;
+
+typedef struct CSR_MLME_DLS_INDICATION
+{
+ CSR_DATAREF SupportedRates;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_SECONDS DlsTimeoutValue;
+} CSR_MLME_DLS_INDICATION;
+
+typedef struct CSR_MLME_DLS_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_SECONDS DlsTimeoutValue;
+ CSR_TIME_UNITS DlsResponseTimeout;
+} CSR_MLME_DLS_REQUEST;
+
+typedef struct CSR_MLME_DLSTEARDOWN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress1;
+ CSR_MACADDRESS PeerMacAddress2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_DLSTEARDOWN_CONFIRM;
+
+typedef struct CSR_MLME_DLSTEARDOWN_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DLSTEARDOWN_INDICATION;
+
+typedef struct CSR_MLME_DLSTEARDOWN_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress1;
+ CSR_MACADDRESS PeerMacAddress2;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DLSTEARDOWN_REQUEST;
+
+typedef struct CSR_MLME_EAPOL_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_PRIORITY ProvidedPriority;
+ CSR_CLIENT_TAG ProvidedHostTag;
+} CSR_MLME_EAPOL_CONFIRM;
+
+typedef struct CSR_MLME_EAPOL_REQUEST
+{
+ CSR_DATAREF Data;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Sa;
+ CSR_MACADDRESS Da;
+ CSR_PRIORITY Priority;
+ CSR_CLIENT_TAG HostTag;
+} CSR_MLME_EAPOL_REQUEST;
+
+typedef struct CSR_MLME_FT_JOIN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_FT_JOIN_CONFIRM;
+
+typedef struct CSR_MLME_FT_JOIN_REQUEST
+{
+ CSR_DATAREF ScanInformationElements;
+ CSR_DATAREF StaInformationElements;
+ CSR_IFINTERFACE Ifindex;
+ CSR_MACADDRESS Bssid;
+ CSR_TIME_UNITS BeaconPeriod;
+ CSR_TSF_TIME Timestamp;
+ CSR_TSF_TIME LocalTime;
+ CSR_CHANNEL_NUMBER Channel;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_BEACON_PERIODS JoinFailureTimeout;
+ CSR_MICROSECONDS32 ProbeDelay;
+} CSR_MLME_FT_JOIN_REQUEST;
+
+typedef struct CSR_MLME_GET_CONFIRM
+{
+ CSR_DATAREF MibAttributeValue;
+ CSR_DATAREF Dummydataref2;
+ CSR_MIB_STATUS Status;
+ CSR_NATURAL16 ErrorIndex;
+} CSR_MLME_GET_CONFIRM;
+
+typedef struct CSR_MLME_GET_REQUEST
+{
+ CSR_DATAREF MibAttribute;
+ CSR_DATAREF Dummydataref2;
+} CSR_MLME_GET_REQUEST;
+
+typedef struct CSR_MLME_GET_NEXT_CONFIRM
+{
+ CSR_DATAREF MibAttributeValue;
+ CSR_DATAREF Dummydataref2;
+ CSR_MIB_STATUS Status;
+ CSR_NATURAL16 ErrorIndex;
+} CSR_MLME_GET_NEXT_CONFIRM;
+
+typedef struct CSR_MLME_GET_NEXT_REQUEST
+{
+ CSR_DATAREF MibAttribute;
+ CSR_DATAREF Dummydataref2;
+} CSR_MLME_GET_NEXT_REQUEST;
+
+typedef struct CSR_MLME_HL_SYNC_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS GroupAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_HL_SYNC_CONFIRM;
+
+typedef struct CSR_MLME_HL_SYNC_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS GroupAddress;
+} CSR_MLME_HL_SYNC_REQUEST;
+
+typedef struct CSR_MLME_HL_SYNC_CANCEL_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS GroupAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_HL_SYNC_CANCEL_CONFIRM;
+
+typedef struct CSR_MLME_HL_SYNC_CANCEL_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS GroupAddress;
+} CSR_MLME_HL_SYNC_CANCEL_REQUEST;
+
+typedef struct CSR_MLME_JOIN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_JOIN_CONFIRM;
+
+typedef struct CSR_MLME_JOIN_REQUEST
+{
+ CSR_DATAREF ScanInformationElements;
+ CSR_DATAREF StaInformationElements;
+ CSR_IFINTERFACE Ifindex;
+ CSR_MACADDRESS Bssid;
+ CSR_TIME_UNITS BeaconPeriod;
+ CSR_TSF_TIME Timestamp;
+ CSR_TSF_TIME LocalTime;
+ CSR_CHANNEL_NUMBER Channel;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_BEACON_PERIODS JoinFailureTimeout;
+ CSR_MICROSECONDS32 ProbeDelay;
+} CSR_MLME_JOIN_REQUEST;
+
+typedef struct CSR_MLME_LINKMEASURE_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_DECIBELS TransmitPower;
+ CSR_DECIBELS MaxTransmitPower;
+} CSR_MLME_LINKMEASURE_REQUEST;
+
+typedef struct CSR_MLME_MEASURE_CONFIRM
+{
+ CSR_DATAREF MeasurementReportSet;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_MEASURE_CONFIRM;
+
+typedef struct CSR_MLME_MEASURE_REQUEST
+{
+ CSR_DATAREF MeasurementRequestSet;
+ CSR_DATAREF Dummydataref2;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_MEASURE_REQUEST;
+
+typedef struct CSR_MLME_MICHAELMICFAILURE_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_NATURAL16 Count;
+ CSR_MACADDRESS Address;
+ CSR_KEY_TYPE KeyType;
+ CSR_NATURAL16 KeyId;
+ CSR_RECEIVE_SEQUENCE_COUNT Tsc;
+} CSR_MLME_MICHAELMICFAILURE_INDICATION;
+
+typedef struct CSR_MLME_MREPORT_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_MREPORT_CONFIRM;
+
+typedef struct CSR_MLME_MREPORT_INDICATION
+{
+ CSR_DATAREF MeasurementReportSet;
+ CSR_DATAREF InformationElements;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_MEASUREMENT_CATEGORY MeasurementCategory;
+} CSR_MLME_MREPORT_INDICATION;
+
+typedef struct CSR_MLME_MREPORT_REQUEST
+{
+ CSR_DATAREF MeasurementReportSet;
+ CSR_DATAREF InformationElements;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_MEASUREMENT_CATEGORY MeasurementCategory;
+} CSR_MLME_MREPORT_REQUEST;
+
+typedef struct CSR_MLME_MREQUEST_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_MREQUEST_CONFIRM;
+
+typedef struct CSR_MLME_MREQUEST_INDICATION
+{
+ CSR_DATAREF MeasurementRequestSet;
+ CSR_DATAREF InformationElements;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_NATURAL16 NumberOfRepetitions;
+ CSR_MEASUREMENT_CATEGORY MeasurementCategory;
+} CSR_MLME_MREQUEST_INDICATION;
+
+typedef struct CSR_MLME_MREQUEST_REQUEST
+{
+ CSR_DATAREF MeasurementRequestSet;
+ CSR_DATAREF InformationElements;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_NATURAL16 NumberOfRepetitions;
+ CSR_MEASUREMENT_CATEGORY MeasurementCategory;
+} CSR_MLME_MREQUEST_REQUEST;
+
+typedef struct CSR_MLME_NEIGHBORREPREQ_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_NEIGHBORREPREQ_CONFIRM;
+
+typedef struct CSR_MLME_NEIGHBORREPREQ_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_NEIGHBORREPREQ_INDICATION;
+
+typedef struct CSR_MLME_NEIGHBORREPREQ_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_NEIGHBORREPREQ_REQUEST;
+
+typedef struct CSR_MLME_NEIGHBORREPRESP_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_NEIGHBORREPRESP_CONFIRM;
+
+typedef struct CSR_MLME_NEIGHBORREPRESP_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_NEIGHBORREPRESP_INDICATION;
+
+typedef struct CSR_MLME_NEIGHBORREPRESP_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+} CSR_MLME_NEIGHBORREPRESP_REQUEST;
+
+typedef struct CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+} CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM;
+
+typedef struct CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+ int16 Pause;
+} CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST;
+
+typedef struct CSR_MLME_PING_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_NATURAL16 TransactionId[8];
+} CSR_MLME_PING_CONFIRM;
+
+typedef struct CSR_MLME_PING_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_NATURAL16 TransactionId[8];
+} CSR_MLME_PING_INDICATION;
+
+typedef struct CSR_MLME_PING_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_NATURAL16 TransactionId[8];
+} CSR_MLME_PING_REQUEST;
+
+typedef struct CSR_MLME_PING_RESPONSE
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_NATURAL16 TransactionId[8];
+} CSR_MLME_PING_RESPONSE;
+
+typedef struct CSR_MLME_POWERMGT_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_POWERMGT_CONFIRM;
+
+typedef struct CSR_MLME_POWERMGT_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_POWER_MANAGEMENT_MODE PowerManagementMode;
+ int16 WakeUp;
+ int16 ReceiveDtims;
+ CSR_BEACON_PERIODS ListenInterval;
+} CSR_MLME_POWERMGT_REQUEST;
+
+typedef struct CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Address1;
+ CSR_MACADDRESS Address2;
+} CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION;
+
+typedef struct CSR_MLME_REASSOCIATE_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS NewApAddress;
+ CSR_TIME_UNITS ReassociateFailureTimeout;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_BEACON_PERIODS ListenInterval;
+} CSR_MLME_REASSOCIATE_REQUEST;
+
+typedef struct CSR_MLME_REMOTE_REQUEST_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_REMOTE_REQUEST_CONFIRM;
+
+typedef struct CSR_MLME_REMOTE_REQUEST_INDICATION
+{
+ CSR_DATAREF ContentOfFtActionFrame;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+} CSR_MLME_REMOTE_REQUEST_INDICATION;
+
+typedef struct CSR_MLME_REMOTE_REQUEST_REQUEST
+{
+ CSR_DATAREF ContentOfFtActionFrame;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+} CSR_MLME_REMOTE_REQUEST_REQUEST;
+
+typedef struct CSR_MLME_RESET_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_RESET_CONFIRM;
+
+typedef struct CSR_MLME_RESET_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS StaAddress;
+ int16 SetDefaultMib;
+} CSR_MLME_RESET_REQUEST;
+
+typedef struct CSR_MLME_RESOURCE_REQUEST_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_RESOURCE_REQUEST_CONFIRM;
+
+typedef struct CSR_MLME_RESOURCE_REQUEST_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+} CSR_MLME_RESOURCE_REQUEST_INDICATION;
+
+typedef struct CSR_MLME_RESOURCE_REQUEST_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+} CSR_MLME_RESOURCE_REQUEST_REQUEST;
+
+typedef struct CSR_MLME_RESOURCE_REQUEST_RESPONSE
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_RESOURCE_REQUEST_RESPONSE;
+
+typedef struct CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM
+{
+ CSR_DATAREF ResourceDescriptors;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS MacAddress;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM;
+
+typedef struct CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST
+{
+ CSR_DATAREF ResourceDescriptors;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS MacAddress;
+} CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST;
+
+typedef struct CSR_MLME_SCAN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_SCAN_CONFIRM;
+
+typedef struct CSR_MLME_SCAN_REQUEST
+{
+ CSR_DATAREF ChannelList;
+ CSR_DATAREF InformationElements;
+ CSR_IFINTERFACE Ifindex;
+ CSR_BSS_TYPE BssType;
+ CSR_MACADDRESS Da;
+ CSR_MACADDRESS Bssid;
+ CSR_SCAN_TYPE ScanType;
+ CSR_MICROSECONDS32 ProbeDelay;
+ CSR_TIME_UNITS MinChannelTime;
+ CSR_TIME_UNITS MaxChannelTime;
+} CSR_MLME_SCAN_REQUEST;
+
+typedef struct CSR_MLME_SCAN_CANCEL_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+} CSR_MLME_SCAN_CANCEL_REQUEST;
+
+typedef struct CSR_MLME_SCHEDULE_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_SCHEDULE_CONFIRM;
+
+typedef struct CSR_MLME_SCHEDULE_INDICATION
+{
+ CSR_DATAREF ScheduleElement;
+ CSR_DATAREF Dummydataref2;
+} CSR_MLME_SCHEDULE_INDICATION;
+
+typedef struct CSR_MLME_SCHEDULE_REQUEST
+{
+ CSR_DATAREF ScheduleElement;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS NonapQstaAddress;
+} CSR_MLME_SCHEDULE_REQUEST;
+
+typedef struct CSR_MLME_SET_CONFIRM
+{
+ CSR_DATAREF MibAttributeValue;
+ CSR_DATAREF Dummydataref2;
+ CSR_MIB_STATUS Status;
+ CSR_NATURAL16 ErrorIndex;
+} CSR_MLME_SET_CONFIRM;
+
+typedef struct CSR_MLME_SET_REQUEST
+{
+ CSR_DATAREF MibAttributeValue;
+ CSR_DATAREF Dummydataref2;
+} CSR_MLME_SET_REQUEST;
+
+typedef struct CSR_MLME_SETKEYS_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_SETKEYS_CONFIRM;
+
+typedef struct CSR_MLME_SETKEYS_REQUEST
+{
+ CSR_DATAREF Key;
+ CSR_DATAREF Dummydataref2;
+ CSR_NATURAL16 Length;
+ CSR_NATURAL16 KeyId;
+ CSR_KEY_TYPE KeyType;
+ CSR_MACADDRESS Address;
+ CSR_RECEIVE_SEQUENCE_COUNT ReceiveSequenceCount;
+ int16 AuthenticatorSupplicantOrInitiatorPeer;
+ CSR_CIPHER_SUITE_SELECTOR CipherSuiteSelector;
+} CSR_MLME_SETKEYS_REQUEST;
+
+typedef struct CSR_MLME_SETPROTECTION_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_SETPROTECTION_CONFIRM;
+
+typedef struct CSR_MLME_SETPROTECTION_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Address;
+ CSR_PROTECT_TYPE ProtectType;
+ CSR_KEY_TYPE KeyType;
+} CSR_MLME_SETPROTECTION_REQUEST;
+
+typedef struct CSR_MLME_SET_UNITDATA_FILTER_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+} CSR_MLME_SET_UNITDATA_FILTER_CONFIRM;
+
+typedef struct CSR_MLME_SET_UNITDATA_FILTER_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_UNIT_DATA_FILTER_MODE UnitDataFilterMode;
+ CSR_IPV4_ADDRESS ArpFilterAddress;
+} CSR_MLME_SET_UNITDATA_FILTER_REQUEST;
+
+typedef struct CSR_MLME_SNIFFJOIN_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE Resultcode;
+} CSR_MLME_SNIFFJOIN_CONFIRM;
+
+typedef struct CSR_MLME_SNIFFJOIN_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_IFINTERFACE Ifindex;
+ CSR_CHANNEL_NUMBER Channel;
+ CSR_CHANNEL_STARTING_FACTOR ChannelStartingFactor;
+} CSR_MLME_SNIFFJOIN_REQUEST;
+
+typedef struct CSR_MLME_STAKEYESTABLISHED_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Address1;
+ CSR_MACADDRESS Address2;
+} CSR_MLME_STAKEYESTABLISHED_INDICATION;
+
+typedef struct CSR_MLME_START_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_MACADDRESS Bssid;
+} CSR_MLME_START_CONFIRM;
+
+typedef struct CSR_MLME_START_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_IFINTERFACE Ifindex;
+ CSR_TIME_UNITS BeaconPeriod;
+ CSR_CHANNEL_NUMBER Channel;
+ CSR_MICROSECONDS32 ProbeDelay;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ int16 BluetoothAmp;
+} CSR_MLME_START_REQUEST;
+
+typedef struct CSR_MLME_TRIGGERED_GET_INDICATION
+{
+ CSR_DATAREF MibAttributeValue;
+ CSR_DATAREF Dummydataref2;
+ CSR_MIB_STATUS Status;
+ CSR_NATURAL16 ErrorIndex;
+ CSR_TRIGGERED_ID TriggeredId;
+} CSR_MLME_TRIGGERED_GET_INDICATION;
+
+typedef struct CSR_MLME_VSPECIFIC_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+} CSR_MLME_VSPECIFIC_REQUEST;
+
+typedef uint16 CSR_PROCESS_ID;
+
+typedef uint16 CSR_RCPI;
+
+typedef uint16 CSR_RSNI;
+
+typedef uint16 CSR_RATE;
+
+typedef uint16 CSR_REPORTED_FRAME;
+
+typedef uint16 CSR_SEQUENCE_NUMBER;
+
+typedef struct CSR_SIGNAL_PRIMITIVE_HEADER
+{
+ int16 SignalId;
+ CSR_PROCESS_ID ReceiverProcessId;
+ CSR_PROCESS_ID SenderProcessId;
+} CSR_SIGNAL_PRIMITIVE_HEADER;
+
+typedef uint32 CSR_TS_INFO;
+
+typedef struct CSR_DEBUG_GENERIC_CONFIRM
+{
+ CSR_DATAREF DebugVariable;
+ CSR_DATAREF Dummydataref2;
+ CSR_NATURAL16 DebugWords[8];
+} CSR_DEBUG_GENERIC_CONFIRM;
+
+typedef struct CSR_DEBUG_GENERIC_INDICATION
+{
+ CSR_DATAREF DebugVariable;
+ CSR_DATAREF Dummydataref2;
+ CSR_NATURAL16 DebugWords[8];
+} CSR_DEBUG_GENERIC_INDICATION;
+
+typedef struct CSR_DEBUG_GENERIC_REQUEST
+{
+ CSR_DATAREF DebugVariable;
+ CSR_DATAREF Dummydataref2;
+ CSR_NATURAL16 DebugWords[8];
+} CSR_DEBUG_GENERIC_REQUEST;
+
+typedef struct CSR_DEBUG_STRING_INDICATION
+{
+ CSR_DATAREF DebugMessage;
+ CSR_DATAREF Dummydataref2;
+} CSR_DEBUG_STRING_INDICATION;
+
+typedef struct CSR_DEBUG_WORD16_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_NATURAL16 DebugWords[16];
+} CSR_DEBUG_WORD16_INDICATION;
+
+typedef struct CSR_DS_STA_NOTIFY_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS StaAddress;
+ CSR_UPDATE_TYPE UpdateType;
+} CSR_DS_STA_NOTIFY_REQUEST;
+
+typedef struct CSR_DS_UNITDATA_INDICATION
+{
+ CSR_DATAREF Data;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Da;
+ CSR_MACADDRESS Sa;
+ CSR_ROUTING_INFORMATION RoutingInformation;
+ CSR_RECEPTION_STATUS ReceptionStatus;
+ CSR_PRIORITY Priority;
+ CSR_SERVICE_CLASS ServiceClass;
+ CSR_CLIENT_TAG HostTag;
+} CSR_DS_UNITDATA_INDICATION;
+
+typedef struct CSR_DS_UNITDATA_REQUEST
+{
+ CSR_DATAREF Data;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Da;
+ CSR_MACADDRESS Sa;
+ CSR_ROUTING_INFORMATION RoutingInformation;
+ CSR_PRIORITY Priority;
+ CSR_SERVICE_CLASS ServiceClass;
+ CSR_SOURCE_TYPE SourceType;
+} CSR_DS_UNITDATA_REQUEST;
+
+typedef struct CSR_DS_UNITDATA_RESPONSE
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Da;
+ CSR_MACADDRESS Sa;
+ CSR_TRANSMISSION_STATUS TransmissionStatus;
+ CSR_ROUTING_INFORMATION RoutingInformation;
+ CSR_PRIORITY ProvidedPriority;
+ CSR_SERVICE_CLASS ProvidedServiceClass;
+ CSR_CLIENT_TAG ProvidedHostTag;
+} CSR_DS_UNITDATA_RESPONSE;
+
+typedef struct CSR_DS_UNITDATA_CANCEL_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_CLIENT_TAG HostTag;
+} CSR_DS_UNITDATA_CANCEL_INDICATION;
+
+typedef struct CSR_MA_SNIFFDATA_INDICATION
+{
+ CSR_DATAREF Data;
+ CSR_DATAREF Dummydataref2;
+ CSR_TSF_TIME Timestamp;
+ CSR_MICROSECONDS16 Duration;
+ CSR_RATE Rate;
+ CSR_ANTENNA_ID AntennaId;
+ CSR_DECIBELS Rssi;
+ CSR_DECIBELS Snr;
+ CSR_HERTZ_DELTA FrequencyOffset;
+ CSR_SNIFFER_RECEPTION_STATUS ReceptionStatus;
+} CSR_MA_SNIFFDATA_INDICATION;
+
+typedef struct CSR_MA_UNITDATA_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Da;
+ CSR_MACADDRESS Sa;
+ CSR_TRANSMISSION_STATUS TransmissionStatus;
+ CSR_PRIORITY ProvidedPriority;
+ CSR_SERVICE_CLASS ProvidedServiceClass;
+ CSR_CLIENT_TAG ProvidedHostTag;
+ CSR_RATE Rate;
+} CSR_MA_UNITDATA_CONFIRM;
+
+typedef struct CSR_MA_UNITDATA_INDICATION
+{
+ CSR_DATAREF Data;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS Da;
+ CSR_MACADDRESS Sa;
+ CSR_ROUTING_INFORMATION RoutingInformation;
+ CSR_RECEPTION_STATUS ReceptionStatus;
+ CSR_PRIORITY Priority;
+ CSR_SERVICE_CLASS ServiceClass;
+ CSR_DECIBELS Rssi;
+ CSR_DECIBELS Snr;
+ CSR_RATE Rate;
+} CSR_MA_UNITDATA_INDICATION;
+
+typedef struct CSR_MLME_ADDBA_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerQstaAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_PRIORITY Tid;
+ CSR_BLOCK_ACK_POLICY BlockAckPolicy;
+ CSR_NATURAL16 BufferSize;
+ CSR_TIME_UNITS BlockAckTimeout;
+ CSR_TIME_UNITS AddbaFailureTimeout;
+ CSR_SEQUENCE_NUMBER BlockAckStartingSequenceControl;
+} CSR_MLME_ADDBA_REQUEST;
+
+typedef struct CSR_MLME_ASSOCIATE_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_ASSOCIATION_ID AssociationId;
+ CSR_RCPI RcpiRequest;
+ CSR_RSNI RsniRequest;
+ CSR_RCPI RcpiResponse;
+ CSR_RSNI RsniResponse;
+} CSR_MLME_ASSOCIATE_CONFIRM;
+
+typedef struct CSR_MLME_ASSOCIATE_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_BEACON_PERIODS ListenInterval;
+ CSR_RCPI RcpiRequest;
+ CSR_RSNI RsniRequest;
+} CSR_MLME_ASSOCIATE_INDICATION;
+
+typedef struct CSR_MLME_ASSOCIATE_RESPONSE
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_RESULT_CODE ResultCode;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_ASSOCIATION_ID AssociationId;
+ CSR_RCPI RcpiRequest;
+ CSR_RSNI RsniRequest;
+} CSR_MLME_ASSOCIATE_RESPONSE;
+
+typedef struct CSR_MLME_AUTONOMOUS_SCAN_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
+ CSR_BSS_TYPE BssType;
+ CSR_MACADDRESS Bssid;
+ CSR_TIME_UNITS BeaconPeriod;
+ CSR_TSF_TIME Timestamp;
+ CSR_TSF_TIME LocalTime;
+ CSR_CHANNEL_NUMBER Channel;
+ CSR_MEGAHERTZ ChannelFrequency;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_DECIBELS Rssi;
+ CSR_DECIBELS Snr;
+ CSR_REPORTED_FRAME ReportedFrameInformation;
+ CSR_RCPI RcpiMeasurement;
+ CSR_RSNI RsniMeasurement;
+} CSR_MLME_AUTONOMOUS_SCAN_INDICATION;
+
+typedef struct CSR_MLME_DELTS_CONFIRM
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_MACADDRESS NonapQstaAddress;
+ CSR_TS_INFO TsInfo;
+} CSR_MLME_DELTS_CONFIRM;
+
+typedef struct CSR_MLME_DELTS_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS NonapQstaAddress;
+ CSR_TS_INFO TsInfo;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DELTS_INDICATION;
+
+typedef struct CSR_MLME_DELTS_REQUEST
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS NonapQstaAddress;
+ CSR_TS_INFO TsInfo;
+ CSR_REASON_CODE ReasonCode;
+} CSR_MLME_DELTS_REQUEST;
+
+typedef struct CSR_MLME_HL_SYNC_INDICATION
+{
+ CSR_DATAREF Dummydataref1;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS GroupAddress;
+ CSR_MACADDRESS SourceAddress;
+ CSR_SEQUENCE_NUMBER SequenceNumber;
+} CSR_MLME_HL_SYNC_INDICATION;
+
+typedef struct CSR_MLME_LINKMEASURE_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_DECIBELS TransmitPower;
+ CSR_DECIBELS LinkMargin;
+ CSR_ANTENNA_ID ReceiveAntennaId;
+ CSR_ANTENNA_ID TransmitAntennaId;
+ CSR_RCPI RcpiRequest;
+ CSR_RSNI RsniRequest;
+ CSR_RCPI RcpiReport;
+ CSR_RSNI RsniReport;
+} CSR_MLME_LINKMEASURE_CONFIRM;
+
+typedef struct CSR_MLME_REASSOCIATE_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_ASSOCIATION_ID AssociationId;
+ CSR_RCPI RcpiRequest;
+ CSR_RSNI RsniRequest;
+ CSR_RCPI RcpiResponse;
+ CSR_RSNI RsniResponse;
+} CSR_MLME_REASSOCIATE_CONFIRM;
+
+typedef struct CSR_MLME_REASSOCIATE_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_MACADDRESS CurrentApAddress;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_BEACON_PERIODS ListenInterval;
+ CSR_RCPI RcpiRequest;
+ CSR_RSNI RsniRequest;
+} CSR_MLME_REASSOCIATE_INDICATION;
+
+typedef struct CSR_MLME_REASSOCIATE_RESPONSE
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerStaAddress;
+ CSR_RESULT_CODE ResultCode;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_ASSOCIATION_ID AssociationId;
+ CSR_RCPI RcpiRequest;
+ CSR_RSNI RsniRequest;
+} CSR_MLME_REASSOCIATE_RESPONSE;
+
+typedef struct CSR_MLME_SCAN_INDICATION
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_IFINTERFACE Ifindex;
+ CSR_BSS_TYPE BssType;
+ CSR_MACADDRESS Bssid;
+ CSR_TIME_UNITS BeaconPeriod;
+ CSR_TSF_TIME Timestamp;
+ CSR_TSF_TIME LocalTime;
+ CSR_CHANNEL_NUMBER Channel;
+ CSR_MEGAHERTZ ChannelFrequency;
+ CSR_CAPABILITY_INFORMATION CapabilityInformation;
+ CSR_DECIBELS Rssi;
+ CSR_DECIBELS Snr;
+ CSR_REPORTED_FRAME ReportedFrameInformation;
+ CSR_RCPI RcpiMeasurement;
+ CSR_RSNI RsniMeasurement;
+} CSR_MLME_SCAN_INDICATION;
+
+typedef struct CSR_MLME_TPCADAPT_CONFIRM
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_RESULT_CODE ResultCode;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_RATE RequestRate;
+ CSR_DECIBELS RequestTransmitPower;
+ CSR_DECIBELS RequestLinkMargin;
+ CSR_RATE ReportRate;
+ CSR_DECIBELS ReportTransmitPower;
+ CSR_DECIBELS ReportLinkMargin;
+} CSR_MLME_TPCADAPT_CONFIRM;
+
+typedef struct CSR_MLME_TPCADAPT_REQUEST
+{
+ CSR_DATAREF InformationElements;
+ CSR_DATAREF Dummydataref2;
+ CSR_MACADDRESS PeerMacAddress;
+ CSR_DIALOG_TOKEN DialogToken;
+ CSR_RATE TransmitRate;
+ CSR_TIME_UNITS TpcadaptFailureTimeout;
+} CSR_MLME_TPCADAPT_REQUEST;
+
+typedef struct CSR_SIGNAL_PRIMITIVE
+{
+ CSR_SIGNAL_PRIMITIVE_HEADER SignalPrimitiveHeader;
+ union
+ {
+ CSR_MA_UNITDATA_REQUEST MaUnitdataRequest;
+ CSR_MA_UNITDATA_CONFIRM MaUnitdataConfirm;
+ CSR_MA_UNITDATA_INDICATION MaUnitdataIndication;
+ CSR_MA_SNIFFDATA_INDICATION MaSniffdataIndication;
+ CSR_MA_UNITDATA_CANCEL_REQUEST MaUnitdataCancelRequest;
+ CSR_MLME_RESET_REQUEST MlmeResetRequest;
+ CSR_MLME_RESET_CONFIRM MlmeResetConfirm;
+ CSR_MLME_GET_REQUEST MlmeGetRequest;
+ CSR_MLME_GET_CONFIRM MlmeGetConfirm;
+ CSR_MLME_SET_REQUEST MlmeSetRequest;
+ CSR_MLME_SET_CONFIRM MlmeSetConfirm;
+ CSR_MLME_GET_NEXT_REQUEST MlmeGetNextRequest;
+ CSR_MLME_GET_NEXT_CONFIRM MlmeGetNextConfirm;
+ CSR_MLME_POWERMGT_REQUEST MlmePowermgtRequest;
+ CSR_MLME_POWERMGT_CONFIRM MlmePowermgtConfirm;
+ CSR_MLME_SCAN_REQUEST MlmeScanRequest;
+ CSR_MLME_SCAN_CONFIRM MlmeScanConfirm;
+ CSR_MLME_SCAN_INDICATION MlmeScanIndication;
+ CSR_MLME_JOIN_REQUEST MlmeJoinRequest;
+ CSR_MLME_JOIN_CONFIRM MlmeJoinConfirm;
+ CSR_MLME_AUTHENTICATE_REQUEST MlmeAuthenticateRequest;
+ CSR_MLME_AUTHENTICATE_CONFIRM MlmeAuthenticateConfirm;
+ CSR_MLME_AUTHENTICATE_RESPONSE MlmeAuthenticateResponse;
+ CSR_MLME_AUTHENTICATE_INDICATION MlmeAuthenticateIndication;
+ CSR_MLME_DEAUTHENTICATE_REQUEST MlmeDeauthenticateRequest;
+ CSR_MLME_DEAUTHENTICATE_CONFIRM MlmeDeauthenticateConfirm;
+ CSR_MLME_DEAUTHENTICATE_INDICATION MlmeDeauthenticateIndication;
+ CSR_MLME_ASSOCIATE_REQUEST MlmeAssociateRequest;
+ CSR_MLME_ASSOCIATE_CONFIRM MlmeAssociateConfirm;
+ CSR_MLME_ASSOCIATE_RESPONSE MlmeAssociateResponse;
+ CSR_MLME_ASSOCIATE_INDICATION MlmeAssociateIndication;
+ CSR_MLME_REASSOCIATE_REQUEST MlmeReassociateRequest;
+ CSR_MLME_REASSOCIATE_CONFIRM MlmeReassociateConfirm;
+ CSR_MLME_REASSOCIATE_RESPONSE MlmeReassociateResponse;
+ CSR_MLME_REASSOCIATE_INDICATION MlmeReassociateIndication;
+ CSR_MLME_DISASSOCIATE_REQUEST MlmeDisassociateRequest;
+ CSR_MLME_DISASSOCIATE_CONFIRM MlmeDisassociateConfirm;
+ CSR_MLME_DISASSOCIATE_INDICATION MlmeDisassociateIndication;
+ CSR_MLME_START_REQUEST MlmeStartRequest;
+ CSR_MLME_START_CONFIRM MlmeStartConfirm;
+ CSR_MLME_ADDTS_REQUEST MlmeAddtsRequest;
+ CSR_MLME_ADDTS_CONFIRM MlmeAddtsConfirm;
+ CSR_MLME_ADDTS_RESPONSE MlmeAddtsResponse;
+ CSR_MLME_ADDTS_INDICATION MlmeAddtsIndication;
+ CSR_MLME_DELTS_REQUEST MlmeDeltsRequest;
+ CSR_MLME_DELTS_CONFIRM MlmeDeltsConfirm;
+ CSR_MLME_DELTS_INDICATION MlmeDeltsIndication;
+ CSR_MLME_DLS_REQUEST MlmeDlsRequest;
+ CSR_MLME_DLS_CONFIRM MlmeDlsConfirm;
+ CSR_MLME_DLS_INDICATION MlmeDlsIndication;
+ CSR_MLME_DLSTEARDOWN_REQUEST MlmeDlsteardownRequest;
+ CSR_MLME_DLSTEARDOWN_CONFIRM MlmeDlsteardownConfirm;
+ CSR_MLME_DLSTEARDOWN_INDICATION MlmeDlsteardownIndication;
+ CSR_MLME_HL_SYNC_REQUEST MlmeHlSyncRequest;
+ CSR_MLME_HL_SYNC_CONFIRM MlmeHlSyncConfirm;
+ CSR_MLME_HL_SYNC_INDICATION MlmeHlSyncIndication;
+ CSR_MLME_ADDBA_REQUEST MlmeAddbaRequest;
+ CSR_MLME_ADDBA_CONFIRM MlmeAddbaConfirm;
+ CSR_MLME_ADDBA_RESPONSE MlmeAddbaResponse;
+ CSR_MLME_ADDBA_INDICATION MlmeAddbaIndication;
+ CSR_MLME_DELBA_REQUEST MlmeDelbaRequest;
+ CSR_MLME_DELBA_CONFIRM MlmeDelbaConfirm;
+ CSR_MLME_DELBA_INDICATION MlmeDelbaIndication;
+ CSR_MLME_SCHEDULE_REQUEST MlmeScheduleRequest;
+ CSR_MLME_SCHEDULE_CONFIRM MlmeScheduleConfirm;
+ CSR_MLME_SCHEDULE_INDICATION MlmeScheduleIndication;
+ CSR_MLME_MREQUEST_REQUEST MlmeMrequestRequest;
+ CSR_MLME_MREQUEST_CONFIRM MlmeMrequestConfirm;
+ CSR_MLME_MREQUEST_INDICATION MlmeMrequestIndication;
+ CSR_MLME_MEASURE_REQUEST MlmeMeasureRequest;
+ CSR_MLME_MEASURE_CONFIRM MlmeMeasureConfirm;
+ CSR_MLME_MREPORT_REQUEST MlmeMreportRequest;
+ CSR_MLME_MREPORT_CONFIRM MlmeMreportConfirm;
+ CSR_MLME_MREPORT_INDICATION MlmeMreportIndication;
+ CSR_MLME_CHANNELSWITCH_REQUEST MlmeChannelswitchRequest;
+ CSR_MLME_CHANNELSWITCH_CONFIRM MlmeChannelswitchConfirm;
+ CSR_MLME_CHANNELSWITCH_RESPONSE MlmeChannelswitchResponse;
+ CSR_MLME_CHANNELSWITCH_INDICATION MlmeChannelswitchIndication;
+ CSR_MLME_TPCADAPT_REQUEST MlmeTpcadaptRequest;
+ CSR_MLME_TPCADAPT_CONFIRM MlmeTpcadaptConfirm;
+ CSR_MLME_SETKEYS_REQUEST MlmeSetkeysRequest;
+ CSR_MLME_SETKEYS_CONFIRM MlmeSetkeysConfirm;
+ CSR_MLME_DELETEKEYS_REQUEST MlmeDeletekeysRequest;
+ CSR_MLME_DELETEKEYS_CONFIRM MlmeDeletekeysConfirm;
+ CSR_MLME_MICHAELMICFAILURE_INDICATION MlmeMichaelmicfailureIndication;
+ CSR_MLME_EAPOL_REQUEST MlmeEapolRequest;
+ CSR_MLME_EAPOL_CONFIRM MlmeEapolConfirm;
+ CSR_MLME_STAKEYESTABLISHED_INDICATION MlmeStakeyestablishedIndication;
+ CSR_MLME_SETPROTECTION_REQUEST MlmeSetprotectionRequest;
+ CSR_MLME_SETPROTECTION_CONFIRM MlmeSetprotectionConfirm;
+ CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION MlmeProtectedframedroppedIndication;
+ CSR_MLME_SNIFFJOIN_REQUEST MlmeSniffjoinRequest;
+ CSR_MLME_SNIFFJOIN_CONFIRM MlmeSniffjoinConfirm;
+ CSR_MLME_CONNECTED_INDICATION MlmeConnectedIndication;
+ CSR_MLME_SCAN_CANCEL_REQUEST MlmeScanCancelRequest;
+ CSR_MLME_LINKMEASURE_REQUEST MlmeLinkmeasureRequest;
+ CSR_MLME_LINKMEASURE_CONFIRM MlmeLinkmeasureConfirm;
+ CSR_MLME_HL_SYNC_CANCEL_REQUEST MlmeHlSyncCancelRequest;
+ CSR_MLME_HL_SYNC_CANCEL_CONFIRM MlmeHlSyncCancelConfirm;
+ CSR_MLME_ADD_PERIODIC_REQUEST MlmeAddPeriodicRequest;
+ CSR_MLME_ADD_PERIODIC_CONFIRM MlmeAddPeriodicConfirm;
+ CSR_MLME_DEL_PERIODIC_REQUEST MlmeDelPeriodicRequest;
+ CSR_MLME_DEL_PERIODIC_CONFIRM MlmeDelPeriodicConfirm;
+ CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST MlmeAddAutonomousScanRequest;
+ CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM MlmeAddAutonomousScanConfirm;
+ CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST MlmeDelAutonomousScanRequest;
+ CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM MlmeDelAutonomousScanConfirm;
+ CSR_MLME_AUTONOMOUS_SCAN_INDICATION MlmeAutonomousScanIndication;
+ CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST MlmeAutonomousScanResultsRequest;
+ CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM MlmeAutonomousScanResultsConfirm;
+ CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION MlmeAutonomousScanResultsIndication;
+ CSR_MLME_SET_UNITDATA_FILTER_REQUEST MlmeSetUnitdataFilterRequest;
+ CSR_MLME_SET_UNITDATA_FILTER_CONFIRM MlmeSetUnitdataFilterConfirm;
+ CSR_MLME_FT_JOIN_REQUEST MlmeFtJoinRequest;
+ CSR_MLME_FT_JOIN_CONFIRM MlmeFtJoinConfirm;
+ CSR_MLME_RESOURCE_REQUEST_REQUEST MlmeResourceRequestRequest;
+ CSR_MLME_RESOURCE_REQUEST_CONFIRM MlmeResourceRequestConfirm;
+ CSR_MLME_RESOURCE_REQUEST_RESPONSE MlmeResourceRequestResponse;
+ CSR_MLME_RESOURCE_REQUEST_INDICATION MlmeResourceRequestIndication;
+ CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST MlmeResourceRequestLocalRequest;
+ CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM MlmeResourceRequestLocalConfirm;
+ CSR_MLME_REMOTE_REQUEST_REQUEST MlmeRemoteRequestRequest;
+ CSR_MLME_REMOTE_REQUEST_CONFIRM MlmeRemoteRequestConfirm;
+ CSR_MLME_REMOTE_REQUEST_INDICATION MlmeRemoteRequestIndication;
+ CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST MlmePauseAutonomousScanRequest;
+ CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM MlmePauseAutonomousScanConfirm;
+ CSR_MLME_NEIGHBORREPREQ_REQUEST MlmeNeighborrepreqRequest;
+ CSR_MLME_NEIGHBORREPREQ_CONFIRM MlmeNeighborrepreqConfirm;
+ CSR_MLME_NEIGHBORREPREQ_INDICATION MlmeNeighborrepreqIndication;
+ CSR_MLME_NEIGHBORREPRESP_REQUEST MlmeNeighborreprespRequest;
+ CSR_MLME_NEIGHBORREPRESP_CONFIRM MlmeNeighborreprespConfirm;
+ CSR_MLME_NEIGHBORREPRESP_INDICATION MlmeNeighborreprespIndication;
+ CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION MlmeAutonomousScanDoneIndication;
+ CSR_MLME_ADD_TRIGGERED_GET_REQUEST MlmeAddTriggeredGetRequest;
+ CSR_MLME_ADD_TRIGGERED_GET_CONFIRM MlmeAddTriggeredGetConfirm;
+ CSR_MLME_DEL_TRIGGERED_GET_REQUEST MlmeDelTriggeredGetRequest;
+ CSR_MLME_DEL_TRIGGERED_GET_CONFIRM MlmeDelTriggeredGetConfirm;
+ CSR_MLME_TRIGGERED_GET_INDICATION MlmeTriggeredGetIndication;
+ CSR_MLME_PING_REQUEST MlmePingRequest;
+ CSR_MLME_PING_CONFIRM MlmePingConfirm;
+ CSR_MLME_PING_RESPONSE MlmePingResponse;
+ CSR_MLME_PING_INDICATION MlmePingIndication;
+ CSR_MLME_VSPECIFIC_REQUEST MlmeVspecificRequest;
+ CSR_MLME_ADD_WDS_REQUEST MlmeAddWdsRequest;
+ CSR_MLME_ADD_WDS_CONFIRM MlmeAddWdsConfirm;
+ CSR_MLME_DEL_WDS_REQUEST MlmeDelWdsRequest;
+ CSR_MLME_DEL_WDS_CONFIRM MlmeDelWdsConfirm;
+ CSR_DS_UNITDATA_REQUEST DsUnitdataRequest;
+ CSR_DS_UNITDATA_RESPONSE DsUnitdataResponse;
+ CSR_DS_UNITDATA_INDICATION DsUnitdataIndication;
+ CSR_DS_UNITDATA_CANCEL_INDICATION DsUnitdataCancelIndication;
+ CSR_DS_STA_NOTIFY_REQUEST DsStaNotifyRequest;
+ CSR_DEBUG_STRING_INDICATION DebugStringIndication;
+ CSR_DEBUG_WORD16_INDICATION DebugWord16Indication;
+ CSR_DEBUG_GENERIC_REQUEST DebugGenericRequest;
+ CSR_DEBUG_GENERIC_CONFIRM DebugGenericConfirm;
+ CSR_DEBUG_GENERIC_INDICATION DebugGenericIndication;
+ } u;
+} CSR_SIGNAL;
+
+#define SIG_FILTER_SIZE 10
+
+uint32 SigGetFilterPos(uint16 aSigID);
+
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi.h b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi.h
new file mode 100644
index 0000000..4d79af9
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi.h
@@ -0,0 +1,384 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE : unifi.h
+ *
+ * PURPOSE : Public API for the driver core.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __UNIFI_H__
+#define __UNIFI_H__ 1
+
+
+/* SDIO chip ID numbers */
+
+/* Manufacturer id */
+#define SDIO_MANF_ID_CSR 0x032A
+
+/* Device id */
+#define SDIO_CARD_ID_UNIFI_1 0x0001
+#define SDIO_CARD_ID_UNIFI_2 0x0002
+#define SDIO_CARD_ID_UNIFI_3 0x0007
+#define SDIO_CARD_ID_UNIFI_4 0x0008
+
+/* Function number for WLAN */
+#define SDIO_WLAN_FUNC_ID_UNIFI_1 0x0001
+#define SDIO_WLAN_FUNC_ID_UNIFI_2 0x0001
+#define SDIO_WLAN_FUNC_ID_UNIFI_3 0x0001
+#define SDIO_WLAN_FUNC_ID_UNIFI_4 0x0002
+
+/* Maximum SDIO bus clock supported. */
+#define UNIFI_SDIO_CLOCK_MAX 25000 /* kHz */
+
+/* I/O default block size to use for UniFi. */
+#define UNIFI_IO_BLOCK_SIZE 64
+
+/*
+ * The number of slots in the from-host queues.
+ *
+ * UNIFI_SOFT_TRAFFIC_Q_LENGTH is the number of slots in the traffic queues
+ * and there will be UNIFI_WME_NO_OF_QS of them.
+ * Traffic queues are used for data packets.
+ *
+ * UNIFI_SOFT_COMMAND_Q_LENGTH is the number of slots in the command queue.
+ * The command queue is used for MLME management requests.
+ *
+ * Queues are ring buffers and so must always have 1 unused slot.
+ */
+#define UNIFI_SOFT_TRAFFIC_Q_LENGTH (20+1)
+#define UNIFI_SOFT_COMMAND_Q_LENGTH (8+1)
+
+
+/*
+ * Structure describing a bulk data slot.
+ * The length field is used to indicate empty/occupied state.
+ * Needs to be defined before #include "unifi_os.h".
+ */
+typedef struct _bulk_data_desc
+{
+ const unsigned char *os_data_ptr;
+ unsigned int data_length;
+ const void *os_net_buf_ptr;
+ unsigned int net_buf_length;
+} bulk_data_desc_t;
+
+
+/* unifi_os.h should be included only in unifi.h */
+#include "unifi_os.h" /* OS definitions from platform directory */
+
+#include "unifi_config.h" /* driver parameters from platform directory */
+#include "driver/unifi_types.h" /* from this dir */
+#include "driver/signals.h" /* from this dir */
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+
+/*
+ * unifi_os.h is responsible for providing definitions for:
+ * EIO
+ * EINVAL
+ * ENODEV
+ * ENOMEM
+ * The values must be distinct, positive integer numbers.
+ */
+
+
+/*
+ * The card structure is an opaque pointer that is used to pass context
+ * to the upper-edge API functions.
+ */
+typedef struct card card_t;
+
+
+/*
+ * This structure describes all of the bulk data that 'might' be
+ * associated with a signal.
+ */
+typedef struct _bulk_data_param
+{
+ bulk_data_desc_t d[UNIFI_MAX_DATA_REFERENCES];
+} bulk_data_param_t;
+
+
+/*
+ * This structure describes the chip and core information
+ * that the core exposes to the OS layer.
+ */
+typedef struct _card_info
+{
+ uint16 chip_id;
+ uint16 chip_version;
+ uint32 fw_build;
+ uint16 fw_hip_version;
+ uint32 sdio_block_size;
+} card_info_t;
+
+
+/* UniFi Deep Sleep Signaling */
+enum unifi_low_power_mode
+{
+ UNIFI_LOW_POWER_DISABLED,
+ UNIFI_LOW_POWER_ENABLED
+};
+
+/* Periodic Wake Host Mode */
+enum unifi_periodic_wake_mode
+{
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED,
+ UNIFI_PERIODIC_WAKE_HOST_ENABLED
+};
+
+/*
+ * Functions that read a portion of a firmware file.
+ */
+#define UNIFI_FW_LOADER 0
+#define UNIFI_FW_STA 1
+void* unifi_fw_read_start(void *ospriv, int is_fw);
+void unifi_fw_read_stop(void *ospriv, void *dlpriv);
+int unifi_fw_read(void *ospriv, void *arg, int offset, void *buf, int len);
+
+
+
+
+/*
+ * UniFi Upper Edge interface
+ */
+
+/* Old SDIO init call - deprecated */
+card_t *unifi_sdio_init(void *sdio, void *ospriv);
+
+/* UniFi driver core initialisation */
+card_t *unifi_alloc_card(void *iopriv, void *ospriv);
+int unifi_init_card(card_t *card, int led_mask);
+/*
+ * unifi_init() and unifi_download() implement a subset of unifi_init_card functionality
+ * that excludes HIP initialization.
+ * They should not be used at the same time with unifi_init_card.
+ */
+int unifi_init(card_t *card);
+
+int unifi_download(card_t *card, int led_mask);
+
+void unifi_free_card(card_t *card);
+
+
+/*
+ * Send signal - Receive event.
+ */
+int unifi_send_signal(card_t *card, const unsigned char *sigptr, int siglen,
+ const bulk_data_param_t *bulkdata);
+void unifi_receive_event(void *ospriv,
+ unsigned char *sigdata, int siglen,
+ const bulk_data_param_t *bulkdata);
+int unifi_send_resources_available(card_t *card, const unsigned char *sigptr);
+
+/* General management functions */
+void unifi_card_info(card_t *card, card_info_t *card_info);
+
+int unifi_check_io_status(card_t *card);
+
+
+/* Botton-Half */
+int unifi_bh(card_t *card, unsigned long *remaining);
+int unifi_run_bh(void *ospriv);
+
+/* UniFi Low Power Mode (Deep Sleep Signaling) */
+int unifi_configure_low_power_mode(card_t *card,
+ enum unifi_low_power_mode low_power_mode,
+ enum unifi_periodic_wake_mode periodic_wake_mode);
+int unifi_force_low_power_mode(card_t *card);
+
+/*
+ * Call-outs from driver core to OS layer.
+ */
+/* Flow control callbacks */
+void unifi_pause_xmit(void *ospriv);
+void unifi_restart_xmit(void *ospriv);
+
+
+
+
+/**
+ * @defgroup bottomedge Bottom edge (SDIO driver interface) API
+ */
+
+int unifi_sdio_enable(void *sdio);
+int unifi_sdio_disable(void *sdio);
+void unifi_sdio_active(void *sdio);
+void unifi_sdio_idle(void *sdio);
+int unifi_sdio_readb(void *sdio, int funcnum,
+ unsigned long addr, unsigned char *pdata);
+int unifi_sdio_writeb(void *sdio, int funcnum,
+ unsigned long addr, unsigned char data);
+int unifi_sdio_block_rw(void *sdio, int funcnum,
+ unsigned long addr, unsigned char *pdata,
+ unsigned int count, int dir_is_write);
+int unifi_sdio_enable_interrupt(void *sdio, int enable);
+int unifi_sdio_set_max_clock_speed(void *sdio, int max_khz);
+
+/**
+ *
+ * Prevent the SDIO driver from removing power from the card.
+ *
+ * If the card is unpowered, switch on power to the card, and
+ * initialize the SDIO interface (including re-writing CCCR register
+ * for bus width, block size etc.).
+ *
+ * @param sdio the SDIO function context.
+ *
+ * @return \b 1 if the power is turned on and UniFi is initialised.
+ *
+ * @return \b 0 if the power is turned on and UniFi needs
+ * to be initialized.
+ *
+ * @return \b -EIO if an I/O error occured while re-initializing the
+ * card. This is a fatal, non-recoverable error.
+ *
+ * @return \b -ENODEV if the card is no longer present.
+ *
+ * @ingroup bottomedge
+ */
+int unifi_sdio_power_on(void *sdio);
+
+/**
+ * Permit the SDIO driver to remove power.
+ *
+ * The SDIO driver may choose to retain power or switch off the power
+ * some time after unifi_sdio_power_off() returns (perhaps because the
+ * power rail supplies other devices or it is not controllable).
+ *
+ * After calling this function unifi_sdio_power_on() must be called
+ * prior to performing further accesses to the card.
+ *
+ * @param sdio the SDIO function context.
+ *
+ * @ingroup bottomedge
+ */
+void unifi_sdio_power_off(void *sdio);
+
+/**
+ * Notify the SDIO driver that the platform is going into the
+ * suspended state. This function may be called in place of
+ * unifi_sdio_power_off() if UniFi power is to be maintained.
+ *
+ * The SDIO driver should stop the SDIO clock and take any other
+ * action to place the SDIO controller hardware into a low-power
+ * state.
+ *
+ * @param sdio the SDIO function context.
+ *
+ * @ingroup bottomedge
+ */
+void unifi_sdio_suspend(void *sdio);
+
+/**
+ * Notify the SDIO driver that the platform is resuming from a
+ * suspended state. This function may be called in place of
+ * unifi_sdio_power_on() if UniFi power was maintained during
+ * suspend.
+ *
+ * The SDIO driver should take any action necessary to restore the
+ * SDIO controller to a working state.
+ *
+ * @param sdio the SDIO function context.
+ *
+ * @ingroup bottomedge
+ */
+void unifi_sdio_resume(void *sdio);
+
+/**
+ * Attempt a hard reset of the UniFi chip.
+ *
+ * If the UniFi Chip is reset (by pulsing the chip's RESET# line low)
+ * the SDIO driver must reinitialize the card (including re-writing
+ * the CCCR register for bus width, block size etc.).
+ *
+ * @param sdio the SDIO function context.
+ *
+ * @return \b 1 if the SDIO driver is not capable of doing a hard
+ * reset.
+ *
+ * @return \b 0 if a hard reset was successfully performed.
+ *
+ * @return \b -EIO if an I/O error occured while re-initializing the
+ * card. This is a fatal, non-recoverable error.
+ *
+ * @return \b -ENODEV if the card is no longer present.
+ *
+ * @ingroup bottomedge
+ */
+int unifi_sdio_hard_reset(void *sdio);
+
+
+void unifi_sdio_interrupt_handler(card_t *card);
+
+
+/* SDIO information */
+enum unifi_sdio_request
+{
+ UNIFI_SDIO_IO_BLOCK_SIZE,
+ UNIFI_SDIO_VENDOR_ID,
+ UNIFI_SDIO_DEVICE_ID,
+ UNIFI_SDIO_FUNCTION_NUM
+};
+int unifi_sdio_get_info(void *sdio, enum unifi_sdio_request param_type, unsigned int *param_value);
+
+
+/* Functions to lookup Unifi signal and bulk data command names. */
+const char *lookup_signal_name(int id);
+const char *lookup_bulkcmd_name(int id);
+
+
+
+/**
+ * Configure the Traffic Analysis sampling
+ *
+ * Enable or disable statistics gathering.
+ * Enable or disable particular packet detection.
+ *
+ * @param card the HIP core context
+ * @param config_type the item to configure
+ * @param config pointer to struct containing config info
+ *
+ * @return \b 0 if configuration was successful
+ *
+ * @return \b -EINVAL if a parameter had an invalid value
+ *
+ * @ingroup trafficanalysis
+ */
+int unifi_ta_configure(card_t *card,
+ unifi_traffic_configtype config_type,
+ const unifi_traffic_config *config);
+
+void unifi_ta_sample(card_t *card,
+ unifi_protocol_direction direction,
+ const bulk_data_desc_t *data,
+ const unsigned char *saddr,
+ const unsigned char *sta_macaddr,
+ uint32 timestamp);
+
+void unifi_ta_classification(card_t *card,
+ unifi_traffic_type traffic_type,
+ uint16 period);
+
+
+/*
+ * Driver must provide these.
+ *
+ * A simple implementation will just call
+ * unifi_sys_traffic_protocol_ind() or unifi_sys_traffic_classification_ind()
+ * respectively. See sme_csr_userspace/sme_userspace.c.
+ */
+void unifi_ta_indicate_protocol(void *ospriv,
+ unifi_traffic_packettype packet_type,
+ unifi_protocol_direction direction,
+ const unifi_MACAddress *src_addr);
+
+void unifi_ta_indicate_sampling(void *ospriv, unifi_traffic_stats *stats);
+
+#endif /* __UNIFI_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_types.h b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_types.h
new file mode 100644
index 0000000..bde5bbc
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_types.h
@@ -0,0 +1,46 @@
+/*
+ *****************************************************************************
+ *
+ * FILE : unifi_types.h
+ *
+ * PURPOSE: Type declarations for UniFi.
+ * This is particularly structures that must be the same on host
+ * (i.e. driver) and chip.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ *****************************************************************************
+ */
+#ifndef __UNIFI_TYPES_H__
+#define __UNIFI_TYPES_H__
+
+
+#ifndef NULL
+#define NULL (0L)
+#endif
+
+/** int8 definition */
+typedef signed char int8;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned long uint32;
+typedef unsigned long long uint64;
+typedef short int16;
+typedef long int32;
+
+
+/* Structure of an entry in the Symbol Look Up Table (SLUT). */
+typedef struct _symbol {
+ uint16 id;
+ uint32 obj;
+} symbol_t;
+
+/** Boolean definition */
+typedef int16 Boolean;
+#define HAVE_BOOLEAN_TYPE 1
+
+
+#endif /* __UNIFI_TYPES_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_udi.h b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_udi.h
new file mode 100644
index 0000000..85a1131
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifi_udi.h
@@ -0,0 +1,49 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: card_udi.h
+ *
+ * PURPOSE:
+ * Declarations and definitions for the UniFi Debug Interface.
+ *
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __UNIFI_UDI_H__
+#define __UNIFI_UDI_H__
+
+#include "driver/unifi.h"
+#include "driver/signals.h"
+
+
+
+/*
+ * Support for tracing the wire protocol.
+ */
+enum udi_log_direction {
+ UDI_LOG_FROM_HOST = 0x0000,
+ UDI_LOG_TO_HOST = 0x0001
+};
+
+typedef void (*udi_func_t)(void *ospriv, unsigned char *sigdata,
+ int signal_len,
+ const bulk_data_param_t *bulkdata,
+ enum udi_log_direction dir);
+
+int unifi_set_udi_hook(card_t *card, udi_func_t udi_fn);
+int unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn);
+
+
+/*
+ * Function to print current status info to a string.
+ * This is used in the linux /proc interface and might be useful
+ * in other systems.
+ */
+int unifi_print_status(card_t *card, char *str);
+
+
+#endif /* __UNIFI_UDI_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/common/driver/unifiversion.h b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifiversion.h
new file mode 100644
index 0000000..02b52eb
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/common/driver/unifiversion.h
@@ -0,0 +1,27 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: unifiversion.h
+ *
+ * PURPOSE:
+ * Version information for the portable UniFi driver.
+ *
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#ifndef __UNIFIVERSION_H__
+#define __UNIFIVERSION_H__
+
+/*
+ * The minimum version of Host Interface Protocol required by the driver.
+ */
+#define UNIFI_HIP_MAJOR_VERSION 6
+#define UNIFI_HIP_MINOR_VERSION 0
+
+
+#endif /* __UNIFIVERSION_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/card.h b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card.h
new file mode 100644
index 0000000..4ac79a6
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card.h
@@ -0,0 +1,97 @@
+/*
+ ******************************************************************************
+ * FILE : card.h
+ *
+ * PURPOSE : Defines abstract interface for hardware specific functions.
+ * Note, this is a different file from one of the same name in the
+ * Windows driver.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *****************************************************************************
+ */
+#ifndef __CARD_H__
+#define __CARD_H__
+
+
+#include "card_sdio.h"
+#include "driver/signals.h"
+#include "driver/unifi_udi.h"
+
+
+
+/*****************************************************************************
+ * CardEnableInt -
+ */
+int CardEnableInt(card_t *card);
+
+/*****************************************************************************
+ * CardGenInt -
+ */
+int CardGenInt(card_t *card);
+
+/*****************************************************************************
+ * CardPendingInt -
+ */
+int CardPendingInt(card_t *card);
+
+/*****************************************************************************
+ * CardDisableInt -
+ */
+int CardDisableInt(card_t *card);
+
+/*****************************************************************************
+ * CardClearInt -
+ */
+int CardClearInt(card_t *card);
+
+/*****************************************************************************
+ * CardDisable -
+ */
+void CardDisable(card_t *card);
+
+/*****************************************************************************
+ * CardIntEnabled -
+ */
+int CardIntEnabled(card_t *card);
+
+/*****************************************************************************
+ * CardGetDataSlotSize
+ */
+int CardGetDataSlotSize(card_t *card);
+
+/*****************************************************************************
+ * CardWriteBulkData -
+ */
+int CardWriteBulkData(card_t *card, bulk_data_desc_t* bulkdata);
+
+/*****************************************************************************
+ * CardClearFromHostDataSlot -
+ */
+void CardClearFromHostDataSlot(card_t *card, const int aSlotNum);
+
+/*****************************************************************************
+ * CardGetFromHostDataSlot -
+ * returns -1 if no slots available
+ */
+int CardGetFromHostDataSlot(card_t *card, unsigned int size);
+
+/*****************************************************************************
+ * CardGetFreeFromHostDataSlots -
+ */
+unsigned int CardGetFreeFromHostDataSlots(card_t *card);
+
+
+int card_stop_processor(card_t *card, int which);
+int card_start_processor(card_t *card, int which);
+
+int card_wait_for_firmware_to_start(card_t *card, unsigned long *paddr);
+
+int unifi_dl_firmware(card_t *card, void *arg, int secondary);
+int unifi_dl_patch(card_t *card, void *arg, unsigned long boot_ctrl);
+int unifi_do_loader_op(card_t *card, unsigned long op_addr, unsigned char opcode);
+
+
+#endif /* __CARD_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.c
new file mode 100644
index 0000000..82345c1
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.c
@@ -0,0 +1,2700 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: card_sdio.c
+ *
+ * PURPOSE: Implementation of the Card API for SDIO.
+ *
+ * NOTES:
+ * CardInit() is called from the SDIO probe callback when a card is
+ * inserted. This performs the basic SDIO initialisation, enabling i/o
+ * etc.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "driver/conversions.h"
+#include "driver/unifiversion.h"
+#include "card.h"
+#include "card_sdio.h"
+#include "chiphelper.h"
+
+
+
+/* Time to wait between attempts to read MAILBOX0 */
+#define MAILBOX1_TIMEOUT 10 /* in millisecs */
+#define MAILBOX1_ATTEMPTS 200 /* 2 seconds */
+
+#define MAILBOX2_TIMEOUT 5 /* in millisecs */
+#define MAILBOX2_ATTEMPTS 10 /* 50ms */
+
+#define MAILBOX2_RESET_ATTEMPTS 10
+#define MAILBOX2_RESET_TIMEOUT 5 /* in millisecs */
+
+#define RESET_SETTLE_DELAY 25 /* in millisecs */
+
+
+static int card_init_slots(card_t *card);
+static int card_hw_init(card_t *card);
+static int firmware_present_in_flash(card_t *card);
+static void bootstrap_chip_hw(card_t *card);
+static int unifi_reset_hardware(card_t *card,
+ enum unifi_reset_type reset_type);
+static int CardHardReset(card_t *card);
+static int CardSoftReset(card_t *card, enum unifi_reset_type reset_type);
+static int unifi_hip_init(card_t *card);
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_init
+ *
+ * Legacy function, kept for backwards compatibility. It doesn't
+ * report enough status when an error occurs to be able to determine
+ * the correct recovery action.
+ * The body is split into:
+ * unifi_init_card()
+ * unifi_alloc_card()
+ *
+ * Arguments:
+ * sdio Pointer to SDIO context pointer to pass to low
+ * level i/o functions.
+ * ospriv Pointer to O/S private struct to pass when calling
+ * callbacks to the higher level system.
+ *
+ * Returns:
+ * Pointer to card struct, which represents the driver context,
+ * or NULL on error.
+ *
+ * Notes:
+ * Doesn't do anything that involves interaction with the SDIO f/w,
+ * as this takes a bit longer to start up.
+ * ---------------------------------------------------------------------------
+ */
+card_t *
+unifi_sdio_init(void *sdio, void *ospriv)
+{
+ card_t *card;
+
+ card = unifi_alloc_card(sdio, ospriv);
+ if (card == NULL) {
+ return NULL;
+ }
+
+ if (unifi_init_card(card, 0x0c00) < 0) {
+ unifi_free_card(card);
+ return NULL;
+ }
+
+ return card;
+
+} /* unifi_sdio_init() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_alloc_card
+ *
+ * Allocate and initialise the card context structure.
+ *
+ * Arguments:
+ * sdio Pointer to SDIO context pointer to pass to low
+ * level i/o functions.
+ * ospriv Pointer to O/S private struct to pass when calling
+ * callbacks to the higher level system.
+ *
+ * Returns:
+ * Pointer to card struct, which represents the driver context or
+ * NULL if the allocation failed.
+ * ---------------------------------------------------------------------------
+ */
+card_t *
+unifi_alloc_card(void *sdio, void *ospriv)
+{
+ card_t *card;
+ unsigned int i;
+
+ func_enter();
+
+
+ card = (card_t*)unifi_malloc(ospriv, sizeof(card_t));
+ if (card == NULL) {
+ return NULL;
+ }
+ memset(card, 0, sizeof(card_t));
+
+
+ card->sdio_if = sdio;
+ card->ospriv = ospriv;
+
+ card->unifi_interrupt_seq = 1;
+
+ /* Make these invalid. */
+ card->proc_select = (unsigned long)(-1);
+ card->dmem_page = (unsigned long)(-1);
+ card->pmem_page = (unsigned long)(-1);
+
+ card->bh_reason_host = 0;
+ card->bh_reason_unifi = 0;
+
+ card->memory_resources_allocated = 0;
+
+ card->low_power_mode = UNIFI_LOW_POWER_DISABLED;
+ card->periodic_wake_mode = UNIFI_PERIODIC_WAKE_HOST_DISABLED;
+
+ card->host_state = UNIFI_HOST_STATE_AWAKE;
+
+ /*
+ * Memory resources for buffers are allocated when the chip is initialised
+ * because we need configuration information from the firmware.
+ */
+
+ /*
+ * Initialise wait queues and lists
+ */
+ card->fh_command_queue.q_body = card->fh_command_q_body;
+ card->fh_command_queue.q_length = UNIFI_SOFT_COMMAND_Q_LENGTH;
+
+ for (i = 0; i < UNIFI_WME_NO_OF_QS; i++) {
+ card->fh_traffic_queue[i].q_body = card->fh_traffic_q_body[i];
+ card->fh_traffic_queue[i].q_length = UNIFI_SOFT_TRAFFIC_Q_LENGTH;
+ }
+
+ func_exit();
+ return card;
+} /* unifi_alloc_card() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_init_card
+ *
+ * Reset the hardware, load the firmware and perform HIP initialization
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 0 on success
+ * 1 success and chip needs firmware download
+ * -ve error code on failure.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_init_card(card_t *card, int led_mask)
+{
+ int r, i;
+
+ func_enter();
+
+ if (card == NULL) {
+ return -EINVAL;
+ }
+
+ /* Reset any state carried forward from a previous life */
+ card->fh_command_queue.q_rd_ptr = 0;
+ card->fh_command_queue.q_wr_ptr = 0;
+ unifi_sprintf(card->fh_command_queue.name, "fh_cmd_q");
+ for (i = 0; i < UNIFI_WME_NO_OF_QS; i++) {
+ card->fh_traffic_queue[i].q_rd_ptr = 0;
+ card->fh_traffic_queue[i].q_wr_ptr = 0;
+ card->fh_pending_unitdata_req[i] = 0;
+ unifi_sprintf(card->fh_traffic_queue[i].name, "fh_data_q%d", i);
+ }
+ unifi_ta_sampling_init(card);
+
+ r = unifi_init(card);
+
+ if (r == 1) {
+ /* chip needs firmware download */
+ r = unifi_download(card, led_mask);
+ } else if (r == 0) {
+ /*
+ * Firmware is running, restore the SDIO bus clock to the normal speed.
+ */
+ r = unifi_sdio_set_max_clock_speed(card->sdio_if, UNIFI_SDIO_CLOCK_MAX);
+ }
+
+ if(r) {
+ return r;
+ }
+
+ r = unifi_hip_init(card);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Failed to start host protocol.\n");
+ return r;
+ }
+
+ func_exit();
+ return 0;
+
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_init
+ *
+ * Init the hardware.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 0 on success and chip doesn't need firmware download
+ * 1 on success and chip needs firmware download
+ * -ve error code on failure.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_init(card_t *card)
+{
+ int r;
+
+ func_enter();
+
+ if (card == NULL) {
+ return -EINVAL;
+ }
+
+
+ /*
+ * UniFi's PLL may start with a slow clock (~ 1 MHz) so initially
+ * set the SDIO bus clock to a similar value or SDIO accesses may
+ * fail.
+ */
+ r = unifi_sdio_set_max_clock_speed(card->sdio_if, 1000);
+ if (r < 0) {
+ return r;
+ }
+
+ /*
+ * Reset UniFi. Note, this only resets the WLAN function part of the chip,
+ * the SDIO interface is not reset.
+ */
+ unifi_trace(card->ospriv, UDBG1, "Resetting UniFi\n");
+ r = unifi_reset_hardware(card, UNIFI_COLD_RESET);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to reset UniFi\n");
+ return r;
+ }
+
+ /*
+ * Set initial value of page registers.
+ * The page registers will be maintained by unifi_read...() and
+ * unifi_write...().
+ */
+ card->proc_select = (unsigned long)(-1);
+ card->dmem_page = (unsigned long)(-1);
+ card->pmem_page = (unsigned long)(-1);
+ r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, 0);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
+ return r;
+ }
+ r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, 0);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write PROG_MEM2_PAGE\n");
+ return r;
+ }
+
+
+ /*
+ * Probe to see if the UniFi has Flash to boot from.
+ * If not (i.e. it needs a RAM download), stop it now to prevent
+ * the watchdog going off.
+ */
+ r = firmware_present_in_flash(card);
+ if (r == -ENODEV) return r;
+ if (r < 0) {
+ unifi_error(card->ospriv, "Probe for Flash failed\n");
+ return r;
+ }
+
+ if (r == 0) {
+ /* needs download */
+ unifi_notice(card->ospriv, "needs firmware\n");
+
+ /* Stop the processor now to avoid confusion if the watchdog goes off
+ */
+ r = card_stop_processor(card, UNIFI_PROC_BOTH);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to stop UniFi processors\n");
+ return r;
+ }
+ /* return 1 to indicate success and chip needs firmware download */
+ r = 1;
+ } else {
+ r = 0;
+ /* return 0 to indicate success and chip doesn't need firmware download */
+ }
+
+ func_exit();
+
+ return r;
+
+} /* unifi_init() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_download
+ *
+ * Load the firmware.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 0 on success
+ * -ve error code on failure.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_download(card_t *card, int led_mask)
+{
+ int r;
+ void *dlpriv;
+ int stage;
+
+ func_enter();
+
+ if (card == NULL) {
+ return -EINVAL;
+ }
+
+ /* Set the loader led mask */
+ card->loader_led_mask = led_mask;
+
+ /* 0 means use CMD52's, 1 means use CMD53's */
+ stage = 0;
+
+ /* Get the loader file information */
+ unifi_trace(card->ospriv, UDBG1, "downloading loader...\n");
+
+ dlpriv = unifi_fw_read_start(card->ospriv, UNIFI_FW_LOADER);
+ if (dlpriv == NULL) {
+ unifi_info(card->ospriv, "No loader found, loading firmware the slow way\n");
+ } else {
+
+ /* Download the loader. */
+ r = unifi_dl_firmware(card, dlpriv, stage);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to download loader\n");
+ return r;
+ }
+
+ /* Free the loader file information. */
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+
+ /* We can now load the firmware with CMD53's */
+ stage++;
+ }
+
+ /*
+ * We have already initialized the PLL.
+ * If the loader is running, we can increase the SDIO clock speed.
+ * If there is no loader, we will use CMD52s to download the f/w.
+ */
+ r = unifi_sdio_set_max_clock_speed(card->sdio_if, UNIFI_SDIO_CLOCK_MAX);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to increase the SDIO clock\n");
+ func_exit();
+ return r;
+ }
+
+ /* Get the firmware file information */
+ unifi_trace(card->ospriv, UDBG1, "downloading firmware...\n");
+
+ dlpriv = unifi_fw_read_start(card->ospriv, UNIFI_FW_STA);
+ if (dlpriv == NULL) {
+ return -ENODATA;
+ }
+
+ /* Download the firmware. */
+ r = unifi_dl_firmware(card, dlpriv, stage);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to download firmware\n");
+ return r;
+ }
+
+ /* Free the firmware file information. */
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+
+ func_exit();
+
+ return 0;
+} /* unifi_download() */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_hip_init
+ *
+ * This function performs the f/w initialisation sequence as described
+ * in the Unifi Host Interface Protocol Specification.
+ * It allocates memory for host-side slot data and signal queues.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 0 on success or else a UniFi error code
+ *
+ * Notes:
+ * The firmware must have been downloaded.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_hip_init(card_t *card)
+{
+ int r;
+
+ func_enter();
+
+ r = card_hw_init(card);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to establish communication with UniFi\n");
+ return r;
+ }
+
+ /*
+ * Allocate memory for host-side slot data and signal queues.
+ * We need the config info read from the firmware to know how much
+ * memory to allocate.
+ */
+ r = card_init_slots(card);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Init slots failed: %d\n", r);
+ return r;
+ }
+
+ unifi_trace(card->ospriv, UDBG2, "Sending first UniFi interrupt\n");
+
+ r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
+ if (r) {
+ return r;
+ }
+
+
+ /* Signal the UniFi to start handling messages */
+ r = CardGenInt(card);
+ if (r) {
+ return r;
+ }
+
+
+ func_exit();
+
+ return 0;
+} /* unifi_hip_init() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * _build_sdio_config_data
+ *
+ * Unpack the SDIO configuration information from a buffer read from
+ * UniFi into a host structure.
+ * The data is byte-swapped for a big-endian host if necessary by the
+ * UNPACK... macros.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * cfg_data Destination structure to unpack into.
+ * cfg_data_buf Source buffer to read from. This should be the raw
+ * data read from UniFi.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+_build_sdio_config_data(sdio_config_data_t *cfg_data,
+ const uint8 *cfg_data_buf)
+{
+ int offset = 0;
+
+ cfg_data->version = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->sdio_ctrl_offset = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->fromhost_sigbuf_handle = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->tohost_sigbuf_handle = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->num_fromhost_sig_frags = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->num_tohost_sig_frags = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->num_fromhost_data_slots = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->num_tohost_data_slots = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->data_slot_size = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->initialised = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->overlay_size = UNPACK32(cfg_data_buf, offset);
+ offset += SIZEOF_UINT32;
+
+ cfg_data->data_slot_round = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->sig_frag_size = UNPACK16(cfg_data_buf, offset);
+ offset += SIZEOF_UINT16;
+
+ cfg_data->tohost_signal_padding = UNPACK16(cfg_data_buf, offset);
+
+} /* _build_sdio_config_data() */
+
+
+
+/*
+ * - Function ----------------------------------------------------------------
+ * card_hw_init()
+ *
+ * Perform the initialisation procedure described in the UniFi Host
+ * Interface Protocol document (section 3.3.8) and read the run-time
+ * configuration information from the UniFi. This is stuff like number
+ * of bulk data slots etc.
+ *
+ * The card enumeration and SD initialisation has already been done by
+ * the SDIO library, see card_sdio_init().
+ *
+ * The initialisation is done when firmware is ready, i.e. this may need
+ * to be called after a f/w download operation.
+ *
+ * The initialisation procedure goes like this:
+ * - Wait for UniFi to start-up by polling SHARED_MAILBOX1
+ * - Find the symbol table and look up SLT_SDIO_SLOT_CONFIG
+ * - Read the config structure
+ * - Check the "SDIO initialised" flag, if not zero do a h/w reset and
+ * start again
+ * - Decide the number of bulk data slots to allocate, allocate them and
+ * set "SDIO initialised" flag (and generate an interrupt) to say so.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 0 on success,
+ * a kernel error code on failure
+ *
+ * Notes:
+ * All data in the f/w is stored in a little endian format, without any
+ * padding bytes. Every read from this memory has to be transformed in
+ * host (cpu specific) format, before it is stored in driver's parameters
+ * or/and structures. Athough unifi_read16() and unifi_read32() do perform
+ * the convertion internally, unifi_readn() does not.
+ * ---------------------------------------------------------------------------
+ */
+static int
+card_hw_init(card_t *card)
+{
+ unsigned long slut_address;
+ uint16 initialised;
+ uint16 finger_print;
+ symbol_t slut;
+ sdio_config_data_t *cfg_data;
+ uint8 cfg_data_buf[SDIO_CONFIG_DATA_SIZE];
+ int r;
+ void *dlpriv;
+ int major, minor;
+ int search_4slut_again;
+
+
+ func_enter();
+
+ /*
+ * The device revision from the TPLMID_MANF and TPLMID_CARD fields
+ * of the CIS are available as
+ * card->sdio_if->pDevice->ManfID
+ * card->sdio_if->pDevice->AppID
+ */
+
+ /*
+ * Run in a loop so we can patch.
+ */
+ do {
+ /* Reset these each time around the loop. */
+ search_4slut_again = 0;
+ cfg_data = NULL;
+
+ r = card_wait_for_firmware_to_start(card, &slut_address);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Firmware hasn't started\n");
+ func_exit();
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG4, "SLUT addr 0x%lX\n", slut_address);
+
+ /*
+ * Check the SLUT fingerprint.
+ * The slut_address is a generic pointer so we must use unifi_read16().
+ */
+ unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n");
+ finger_print = 0;
+ r = unifi_read16(card, slut_address, &finger_print);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
+ func_exit();
+ return r;
+ }
+
+ if (finger_print != SLUT_FINGERPRINT) {
+ unifi_error(card->ospriv, "Failed to find Symbol lookup table fingerprint\n");
+ func_exit();
+ return -EIO;
+ }
+
+ /* Symbol table starts imedately after the fingerprint */
+ slut_address += 2;
+
+ while (1) {
+ uint16 s;
+ uint32 l;
+
+ r = unifi_read16(card, slut_address, &s);
+ if (r < 0) {
+ func_exit();
+ return r;
+ }
+ slut_address += 2;
+
+ if (s == CSR_SLT_END) {
+ break;
+ }
+
+ r = unifi_read32(card, slut_address, &l);
+ if (r < 0) {
+ func_exit();
+ return r;
+ }
+ slut_address += 4;
+
+ slut.id = s;
+ slut.obj = l;
+
+ unifi_trace(card->ospriv, UDBG3, " found SLUT id %02d.%08lx\n", slut.id, slut.obj);
+ switch (slut.id) {
+
+ case CSR_SLT_SDIO_SLOT_CONFIG:
+ cfg_data = &card->config_data;
+ /*
+ * unifi_readn reads n bytes from the card, where data is stored
+ * in a little endian format, without any padding bytes. So, we
+ * can not just pass the cfg_data pointer or use the
+ * sizeof(sdio_config_data_t) since the structure in the host can
+ * be big endian formatted or have padding bytes for alignment.
+ * We use a char buffer to read the data from the card.
+ */
+ r = unifi_readn(card, slut.obj, cfg_data_buf, SDIO_CONFIG_DATA_SIZE);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read config data\n");
+ func_exit();
+ return r;
+ }
+ /* .. and then we copy the data to the host structure */
+ _build_sdio_config_data(cfg_data, cfg_data_buf);
+
+#ifdef UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE
+ /*
+ * To force the To-Host signals to be rounded up to the SDIO block
+ * size, we need to write the To-Host Signal Padding Fragments
+ * field of the SDIO configuration in UniFi.
+ */
+ if ((card->sdio_io_block_size % cfg_data->sig_frag_size) != 0) {
+ unifi_error(card->ospriv, "Configuration error: Can not pad to-host signals.\n");
+ func_exit();
+ return -EINVAL;
+ }
+ cfg_data->tohost_signal_padding = (uint16) (card->sdio_io_block_size / cfg_data->sig_frag_size);
+ r = unifi_write16(card, slut.obj + SDIO_TO_HOST_SIG_PADDING_OFFSET, cfg_data->tohost_signal_padding);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write To-Host Signal Padding Fragments\n");
+ func_exit();
+ return r;
+ }
+#endif
+
+ /* Reconstruct the Generic Pointer address of the
+ * SDIO Control Data Struct.
+ */
+ card->sdio_ctrl_addr = cfg_data->sdio_ctrl_offset | (UNIFI_SH_DMEM << 24);
+ card->init_flag_addr = slut.obj + SDIO_INIT_FLAG_OFFSET;
+ break;
+
+ case CSR_SLT_BUILD_ID_NUMBER:
+ {
+ uint32 n;
+ r = unifi_read32(card, slut.obj, &n);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read build id\n");
+ func_exit();
+ return r;
+ }
+ card->build_id = n;
+ }
+ break;
+
+ case CSR_SLT_BUILD_ID_STRING:
+ r = unifi_readnz(card, slut.obj, card->build_id_string,
+ sizeof(card->build_id_string));
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read build string\n");
+ func_exit();
+ return r;
+ }
+ break;
+
+ case CSR_SLT_PERSISTENT_STORE_DB:
+ break;
+
+ case CSR_SLT_BOOT_LOADER_CONTROL:
+
+ /* This command copies most of the station firmware
+ * image from ROM into program RAM. It also clears
+ * out the zerod data and sets up the initialised
+ * data. */
+ r = unifi_do_loader_op(card, slut.obj+6, UNIFI_BOOT_LOADER_LOAD_STA);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write loader load image command\n");
+ func_exit();
+ return r;
+ }
+
+ dlpriv = unifi_fw_read_start(card->ospriv, UNIFI_FW_STA);
+
+ /* dlpriv might be NULL, we still need to do the do_loader_op step. */
+ if (dlpriv != NULL) {
+ /* Download the firmware. */
+ r = unifi_dl_patch(card, dlpriv, slut.obj);
+
+ /* Free the firmware file information. */
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+
+ if (r) {
+ unifi_error(card->ospriv, "Failed to patch firmware\n");
+ func_exit();
+ return r;
+ }
+ }
+
+ /* This command starts the firmware image that we want (the
+ * station by default) with any patches required applied. */
+ r = unifi_do_loader_op(card, slut.obj+6, UNIFI_BOOT_LOADER_RESTART);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write loader restart command\n");
+ func_exit();
+ return r;
+ }
+
+ search_4slut_again = 1;
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+ } while (search_4slut_again);
+
+ /* Did we find the Config Data ? */
+ if (cfg_data == NULL) {
+ unifi_error(card->ospriv, "Failed to find SDIO_SLOT_CONFIG Symbol\n");
+ func_exit();
+ return -EIO;
+ }
+
+ /*
+ * Has ths card already been initialised?
+ * If so, return an error so we do a h/w reset and start again.
+ */
+ r = unifi_read16(card, card->init_flag_addr, &initialised);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read init flag at %08lx\n",
+ card->init_flag_addr);
+ func_exit();
+ return r;
+ }
+ if (initialised != 0) {
+ func_exit();
+ return -EIO;
+ }
+
+
+ /*
+ * Now check the UniFi firmware version
+ */
+ major = (cfg_data->version >> 8) & 0xFF;
+ minor = cfg_data->version & 0xFF;
+ unifi_info(card->ospriv, "UniFi f/w protocol version %d.%d (driver %d.%d)\n",
+ major, minor,
+ UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
+
+ unifi_info(card->ospriv, "Firmware build %d: %s\n",
+ card->build_id, card->build_id_string);
+
+ if (major != UNIFI_HIP_MAJOR_VERSION) {
+ unifi_error(card->ospriv, "UniFi f/w protocol major version is different from driver (v%d.%d)\n",
+ UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
+ func_exit();
+ return -EIO;
+ }
+ if (minor < UNIFI_HIP_MINOR_VERSION) {
+ unifi_error(card->ospriv, "UniFi f/w protocol version (v%d.%d) is older than minimum required by driver (v%d.%d).\n",
+ major, minor,
+ UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
+ func_exit();
+ return -EIO;
+ }
+
+ func_exit();
+ return 0;
+
+} /* card_hw_init() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_wait_for_unifi_to_reset
+ *
+ * Waits for a reset to complete by polling the WLAN function enable
+ * bit (which is cleared on reset).
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 0 on success, UniFi error code on failure.
+ * ---------------------------------------------------------------------------
+ */
+static int
+card_wait_for_unifi_to_reset(card_t *card)
+{
+ int i, r;
+ uint8 io_enable;
+
+ r = 0;
+ for (i = 0; i < MAILBOX2_ATTEMPTS; i++) {
+ unifi_trace(card->ospriv, UDBG1, "waiting for reset to complete, attempt %d\n", i);
+ if (card->chip_id > SDIO_CARD_ID_UNIFI_2) {
+ /* It's quite likely that this read will timeout for the
+ * first few tries - especially if we have reset via
+ * DBG_RESET. */
+ r = sdio_read_f0(card, SDIO_IO_READY, &io_enable);
+ } else {
+ r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_enable);
+ }
+ if (r == -ENODEV) return r;
+ if (r == 0) {
+ uint16 mbox2;
+ int enabled = io_enable & (1 << card->function);
+
+ if (!enabled) {
+ unifi_trace(card->ospriv, UDBG1,
+ "Reset complete (function %d is disabled) in ~ %u msecs\n",
+ card->function, i * MAILBOX2_TIMEOUT);
+
+ /* Enable WLAN function and verify MAILBOX2 is zero'd */
+ r = unifi_sdio_enable(card->sdio_if);
+ if (r) {
+ unifi_error(card->ospriv, "unifi_sdio_enable failed %d\n", r);
+ break;
+ }
+ r = unifi_read_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, &mbox2);
+ if (r)
+ {
+ unifi_error(card->ospriv, "read HIP_HANDSHAKE failed %d\n", r);
+ break;
+ }
+ if (mbox2 != 0) {
+ unifi_error(card->ospriv, "MAILBOX2 non-zero after reset (mbox2 = %04x)\n", mbox2);
+ r = -EIO;
+ }
+ break;
+ }
+ } else {
+ if (card->chip_id > SDIO_CARD_ID_UNIFI_2) {
+ /* We ignore read failures for the first few reads,
+ * they are probably benign. */
+ if (i > MAILBOX2_ATTEMPTS / 4) {
+ unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Ready register while polling for reset\n");
+ }
+ } else {
+ unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Enable register while polling for reset\n");
+ }
+ }
+ unifi_sleep_ms(card->ospriv, MAILBOX2_TIMEOUT);
+ }
+
+ if ((r == 0) && (i == MAILBOX2_ATTEMPTS)) {
+ unifi_trace(card->ospriv, UDBG1, "Timeout waiting for UniFi to complete reset\n");
+ r = -ETIMEDOUT;
+ }
+
+ return r;
+} /* card_wait_for_unifi_to_reset() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_wait_for_firmware_to_start
+ *
+ * Polls the MAILBOX1 register for a non-zero value.
+ * Then reads MAILBOX0 and forms the two values into a 32-bit address
+ * which is returned to the caller.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * paddr Pointer to receive the UniFi address formed
+ * by concatenating MAILBOX1 and MAILBOX0.
+ *
+ * Returns:
+ * 0 on success, error code on failure.
+ * ---------------------------------------------------------------------------
+ */
+int
+card_wait_for_firmware_to_start(card_t *card, unsigned long *paddr)
+{
+ int i, r;
+ uint16 mbox0, mbox1;
+
+ /*
+ * Wait for UniFi to initialise its data structures by polling
+ * the SHARED_MAILBOX1 register.
+ * Experience shows this is typically 120ms.
+ */
+ unifi_sleep_ms(card->ospriv, MAILBOX1_TIMEOUT);
+
+ mbox1 = 0;
+ unifi_trace(card->ospriv, UDBG1, "waiting for MAILBOX1 to be non-zero...\n");
+ for (i = 0; i < MAILBOX1_ATTEMPTS; i++)
+ {
+ r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1);
+ if (r == -ENODEV) return r;
+ if (r) {
+ /* These reads can fail if UniFi isn't up yet, so try again */
+ unifi_warning(card->ospriv, "Failed to read UniFi Mailbox1 register\n");
+ }
+
+ if ((r == 0) && (mbox1 != 0)) {
+ unifi_trace(card->ospriv, UDBG1, "MAILBOX1 ready (0x%04X) in %u millisecs\n",
+ mbox1, i * MAILBOX1_TIMEOUT);
+
+ /* Read the MAILBOX1 again in case we caught the value as it
+ * changed. */
+ r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read UniFi Mailbox1 register for second time\n");
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG1, "MAILBOX1 value=0x%04X\n", mbox1);
+
+ break;
+ }
+
+ unifi_sleep_ms(card->ospriv, MAILBOX1_TIMEOUT);
+ if ((i % 100) == 99) {
+ unifi_trace(card->ospriv, UDBG2, "MAILBOX1 not ready (0x%X), still trying...\n", mbox1);
+ }
+ }
+
+ if ((r == 0) && (mbox1 == 0)) {
+ unifi_trace(card->ospriv, UDBG1, "Timeout waiting for firmware to start, Mailbox1 still 0 after %d ms\n",
+ MAILBOX1_ATTEMPTS * MAILBOX1_TIMEOUT);
+ return -EIO;
+ }
+
+
+ /*
+ * Complete the reset handshake by setting MAILBOX2 to 0xFFFF
+ */
+ r = unifi_write_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, 0xFFFF);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write f/w startup handshake to MAILBOX2\n");
+ return r;
+ }
+
+
+ /*
+ * Read the Symbol Look Up Table (SLUT) offset.
+ * Top 16 bits are in mbox1, read the lower 16 bits from mbox0.
+ */
+ mbox0 = 0;
+ r = unifi_read_direct16(card, ChipHelper_MAILBOX0(card->helper) * 2, &mbox0);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read UniFi Mailbox0 register\n");
+ return r;
+ }
+
+ *paddr = (((unsigned long)mbox1 << 16) | mbox0);
+
+ return 0;
+} /* card_wait_for_firmware_to_start() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_allocate_memory_resources
+ *
+ * Allocates memory for the from-host, to-host bulk data slots,
+ * soft queue buffers and bulk data buffers.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 0 on success, error code on failure.
+ * ---------------------------------------------------------------------------
+ */
+static int
+card_allocate_memory_resources(card_t *card)
+{
+ unsigned int n, i, k, r;
+ sdio_config_data_t *cfg_data;
+
+ func_enter();
+
+ /* Convenience short-cut */
+ cfg_data = &card->config_data;
+
+
+ /*
+ * Allocate memory for the from-host and to-host signal buffers.
+ */
+ card->fh_buffer.buf = unifi_malloc(card->ospriv, UNIFI_FH_BUF_SIZE);
+ if (card->fh_buffer.buf == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n");
+ return -ENOMEM;
+ }
+ card->fh_buffer.bufsize = UNIFI_FH_BUF_SIZE;
+ card->fh_buffer.ptr = card->fh_buffer.buf;
+ card->fh_buffer.count = 0;
+
+ card->th_buffer.buf = unifi_malloc(card->ospriv, UNIFI_FH_BUF_SIZE);
+ if (card->th_buffer.buf == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n");
+ return -ENOMEM;
+ }
+ card->th_buffer.bufsize = UNIFI_FH_BUF_SIZE;
+ card->th_buffer.ptr = card->th_buffer.buf;
+ card->th_buffer.count = 0;
+
+
+
+ /*
+ * Allocate memory for the from-host and to-host bulk data slots.
+ * This is done as separate unifi_mallocs because lots of smaller
+ * allocations are more likely to succeed than one huge one.
+ */
+
+ /* Allocate memory for the array of pointers */
+ n = cfg_data->num_fromhost_data_slots;
+
+ unifi_trace(card->ospriv, UDBG3, "Alloc from-host resources, %d slots.\n", n);
+ card->from_host_data =
+ (bulk_data_desc_t*)unifi_malloc(card->ospriv, n * sizeof(bulk_data_desc_t));
+ if (card->from_host_data == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate memory for F-H bulk data array\n");
+ return -ENOMEM;
+ }
+
+ /* Initialise from-host bulk data slots */
+ for (i = 0; i < n; i++) {
+ unifi_init_bulk_data(&card->from_host_data[i]);
+ }
+
+
+ /* Allocate memory for the array of pointers */
+ n = cfg_data->num_tohost_data_slots;
+
+ unifi_trace(card->ospriv, UDBG3, "Alloc to-host resources, %d slots.\n", n);
+ card->to_host_data =
+ (bulk_data_desc_t*)unifi_malloc(card->ospriv, n * sizeof(bulk_data_desc_t));
+ if (card->to_host_data == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate memory for T-H bulk data array\n");
+ return -ENOMEM;
+ }
+
+ /* Initialise to-host bulk data slots */
+ for (i = 0; i < n; i++) {
+ unifi_init_bulk_data(&card->to_host_data[i]);
+ }
+
+ /*
+ * Initialise buffers for soft Q
+ */
+ for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++) {
+ for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) {
+ unifi_init_bulk_data(&card->fh_command_q_body[i].bulkdata[r]);
+ }
+ }
+
+ for (k = 0; k < UNIFI_WME_NO_OF_QS; k++) {
+ for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++) {
+ for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) {
+ unifi_init_bulk_data(&card->fh_traffic_q_body[k][i].bulkdata[r]);
+ }
+ }
+ }
+
+ card->memory_resources_allocated = 1;
+
+ func_exit();
+ return 0;
+} /* card_allocate_memory_resources() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_free_bulk_data
+ *
+ * Free the data associated to a bulk data structure.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * bulk_data_slot Pointer to bulk data structure
+ *
+ * Returns:
+ * None.
+ *
+ * ---------------------------------------------------------------------------
+ */
+static void
+unifi_free_bulk_data(card_t *card, bulk_data_desc_t *bulk_data_slot)
+{
+ if (bulk_data_slot->data_length != 0) {
+ unifi_net_data_free(card->ospriv, bulk_data_slot);
+ }
+} /* unifi_free_bulk_data() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_free_memory_resources
+ *
+ * Frees memory allocated for the from-host, to-host bulk data slots,
+ * soft queue buffers and bulk data buffers.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+card_free_memory_resources(card_t *card)
+{
+ int i, n, r;
+ func_enter();
+
+ unifi_trace(card->ospriv, UDBG1, "Freeing card memory resources.\n");
+
+ if (card->to_host_data) {
+ /*
+ * Free any bulk data buffers allocated for the t-h slots
+ * This will clear all buffers that did not make it to
+ * unifi_receive_event() before UniFi was removed.
+ */
+ n = card->config_data.num_tohost_data_slots;
+ unifi_trace(card->ospriv, UDBG3, "Freeing to-host resources, %d slots.\n", n);
+ for (i = 0; i < n; i++) {
+ unifi_free_bulk_data(card, &card->to_host_data[i]);
+ }
+ unifi_free(card->ospriv, card->to_host_data);
+ card->to_host_data = NULL;
+ }
+
+ /*
+ * If any of the from-host bulk data has reached the card->from_host_data
+ * but not UniFi, we need to free the buffers here.
+ */
+ if (card->from_host_data) {
+ /* Free any bulk data buffers allocated for the f-h slots */
+ n = card->config_data.num_fromhost_data_slots;
+ unifi_trace(card->ospriv, UDBG3, "Freeing from-host resources, %d slots.\n", n);
+ for (i = 0; i < n; i++) {
+ unifi_free_bulk_data(card, &card->from_host_data[i]);
+ }
+ unifi_free(card->ospriv, card->from_host_data);
+ card->from_host_data = NULL;
+ }
+
+ /*
+ * Free any bulk data buffers allocated in the soft queues.
+ * This covers the case where a bulk data pointer has reached the soft queue
+ * but not the card->from_host_data.
+ */
+ unifi_trace(card->ospriv, UDBG3, "Freeing cmd q resources.\n");
+ for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++) {
+ for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) {
+ unifi_free_bulk_data(card, &card->fh_command_q_body[i].bulkdata[r]);
+ }
+ }
+
+ unifi_trace(card->ospriv, UDBG3, "Freeing traffic q resources.\n");
+ for (n = 0; n < UNIFI_WME_NO_OF_QS; n++) {
+ for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++) {
+ for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++) {
+ unifi_free_bulk_data(card, &card->fh_traffic_q_body[n][i].bulkdata[r]);
+ }
+ }
+ }
+
+ if (card->fh_buffer.buf) {
+ unifi_free(card->ospriv, card->fh_buffer.buf);
+ }
+ card->fh_buffer.ptr = card->fh_buffer.buf = NULL;
+ card->fh_buffer.bufsize = 0;
+ card->fh_buffer.count = 0;
+
+ if (card->th_buffer.buf) {
+ unifi_free(card->ospriv, card->th_buffer.buf);
+ }
+ card->th_buffer.ptr = card->th_buffer.buf = NULL;
+ card->th_buffer.bufsize = 0;
+ card->th_buffer.count = 0;
+
+
+ card->memory_resources_allocated = 0;
+
+ func_exit();
+} /* card_free_memory_resources() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_free_card
+ *
+ * Free the memory allocated for the card structure and buffers.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_free_card(card_t *card)
+{
+ void *ospriv = card->ospriv;
+
+ /* Free any memory allocated. */
+ card_free_memory_resources(card);
+
+ unifi_free(ospriv, card);
+
+} /* unifi_free_card() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_init_slots
+ *
+ * Allocate memory for host-side slot data and signal queues.
+ *
+ * Arguments:
+ * card Pointer to card object
+ *
+ * Returns:
+ * Kernel error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+card_init_slots(card_t *card)
+{
+ int r;
+
+ func_enter();
+
+ /* Allocate the buffers we need, only once. */
+ if (card->memory_resources_allocated == 1) {
+ card_free_memory_resources(card);
+ }
+
+ r = card_allocate_memory_resources(card);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to allocate card memory resources.\n");
+ card_free_memory_resources(card);
+ return r;
+ }
+
+ if (card->sdio_ctrl_addr == 0) {
+ unifi_error(card->ospriv, "Failed to find config struct!\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Set initial counts.
+ */
+
+ card->from_host_data_head = 0;
+
+ /* Get initial signal counts from UniFi, in case it has not been reset. */
+ {
+ uint16 s;
+ /* Get the from-host-signals-written count */
+ r = unifi_read16(card, card->sdio_ctrl_addr+0, &s);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read from-host sig read count\n");
+ return r;
+ }
+ card->from_host_signals_w = (int)s;
+
+ /* Get the from-host-signals-written count */
+ r = unifi_read16(card, card->sdio_ctrl_addr+6, &s);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read from-host sig read count\n");
+ return r;
+ }
+ card->to_host_signals_r = (int)s;
+ }
+
+ /* Set Initialised flag. */
+ r = unifi_write16(card, card->init_flag_addr, 0x0001);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write initialised flag\n");
+ return r;
+ }
+
+ func_exit();
+ return 0;
+
+} /* card_init_slots() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_set_udi_hook
+ *
+ * Registers the udi hook that reports the sent signals to the core.
+ *
+ * Arguments:
+ * card Pointer to the card context struct
+ * udi_fn Pointer to the callback function.
+ *
+ * Returns:
+ * -EINVAL if the card pointer is invalid, 0 on success.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_set_udi_hook(card_t *card, udi_func_t udi_fn)
+{
+ if (card == NULL) {
+ return -EINVAL;
+ }
+
+ if (card->udi_hook == NULL) {
+ card->udi_hook = udi_fn;
+ }
+
+ return 0;
+} /* unifi_set_udi_hook() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_remove_udi_hook
+ *
+ * Removes the udi hook that reports the sent signals from the core.
+ *
+ * Arguments:
+ * card Pointer to the card context struct
+ * udi_fn Pointer to the callback function.
+ *
+ * Returns:
+ * -EINVAL if the card pointer is invalid, 0 on success.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn)
+{
+ if (card == NULL) {
+ return -EINVAL;
+ }
+
+ if (card->udi_hook == udi_fn) {
+ card->udi_hook = NULL;
+ }
+
+ return 0;
+} /* unifi_remove_udi_hook() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardGetFromHostDataSlot
+ *
+ * Find a free from-host bulk data slot.
+ * A slot is free if it's length member is zero.
+ * This function returns the slot number or error code if a slot
+ * is not available.
+ *
+ * Arguments:
+ * card Pointer to the card context struct
+ * len Number of bytes of bulk data that the slot will carry.
+ *
+ * Returns:
+ * The index of a free slot in the from_host_data array or
+ * -1 if no slot is available.
+ * ---------------------------------------------------------------------------
+ */
+int
+CardGetFromHostDataSlot(card_t *card, unsigned int len)
+{
+ int i, s, h;
+ int nslots;
+
+ func_enter();
+
+ s = -1;
+ nslots = card->config_data.num_fromhost_data_slots;
+
+ ASSERT(len);
+ ASSERT(len <= card->config_data.data_slot_size);
+
+#if 0
+ /* Check if there are free slots */
+ if (card->fh_data_slots_free == 0) {
+ unifi_error(card->ospriv, "No from-host data slots free\n");
+ return -1;
+ }
+#endif
+
+ h = card->from_host_data_head;
+
+ for (i = 0; i < nslots; i++)
+ {
+ int hh = h;
+
+ /* Advance head pointer */
+ if (++h >= nslots) {
+ h -= nslots;
+ }
+
+ if (card->from_host_data[hh].data_length == 0) {
+ /* Free data slot, claim it */
+ s = hh;
+ break;
+ }
+ }
+ card->from_host_data_head = h;
+
+ /* If we found a slot then return */
+
+ /*
+ * We should be guaranteed a free slot, report an error if we
+ * didn't find one.
+ */
+ if (s < 0) {
+ unifi_error(card->ospriv, "Internal error, didn't find a free data slot\n");
+ for (i = 0; i < nslots; i++) {
+ unifi_error(card->ospriv, "fh data slot %d: %d\n", i, card->from_host_data[i].data_length);
+ }
+ }
+
+ unifi_trace(card->ospriv, UDBG4, "CardGetFromHostDataSlot: slot %d, p:0x%x, %d bytes\n", s, &len, len);
+
+ return s;
+} /* CardGetFromHostDataSlot() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardClearFromHostDataSlot
+ *
+ * Clear a the given data slot, making it available again.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ * slot Index of the signal slot to clear.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+CardClearFromHostDataSlot(card_t *card, const int slot)
+{
+ func_enter();
+
+ if (card->from_host_data[slot].data_length == 0) {
+ unifi_warning(card->ospriv,
+ "Surprise: request to clear an already free FH data slot: %d\n",
+ slot);
+ func_exit();
+ return;
+ }
+
+ /* Free card->from_host_data[slot].os_net_ptr here. */
+ /* Mark slot as free by setting length to 0. */
+ if (card->from_host_data[slot].data_length) {
+ unifi_free_bulk_data(card, &card->from_host_data[slot]);
+ }
+
+ unifi_trace(card->ospriv, UDBG4, "CardClearFromHostDataSlot: slot %d recycled\n", slot);
+
+ func_exit();
+} /* CardClearFromHostDataSlot() */
+
+
+
+int
+CardGetDataSlotSize(card_t *card)
+{
+ return card->config_data.data_slot_size;
+} /* CardGetDataSlotSize() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardGetFreeFromHostDataSlots
+ *
+ * Retrieve the number of from-host bulk data slots available.
+ *
+ * Arguments:
+ * card Pointer to the card context struct
+ *
+ * Returns:
+ * Number of free from-host bulk data slots.
+ * ---------------------------------------------------------------------------
+ */
+unsigned int
+CardGetFreeFromHostDataSlots(card_t *card)
+{
+ unsigned int nslots;
+ unsigned int i, n = 0;
+
+ nslots = card->config_data.num_fromhost_data_slots;
+
+ for (i = 0; i < nslots; i++)
+ if (card->from_host_data[i].data_length == 0)
+ n++;
+
+ return n;
+} /* CardGetFreeFromHostDataSlots() */
+
+
+
+static int
+unifi_identify_hw(card_t *card)
+{
+ int r;
+ unsigned int t;
+
+ /*
+ * Retrieve the device ID from the SDIO driver.
+ */
+ r = unifi_sdio_get_info(card->sdio_if, UNIFI_SDIO_DEVICE_ID, &card->chip_id);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read UNIFI_SDIO_DEVICE_ID\n");
+ return r;
+ }
+
+ /* Get the function number from the SDIO driver. */
+ r = unifi_sdio_get_info(card->sdio_if, UNIFI_SDIO_FUNCTION_NUM, &t);
+ if (r) {
+ unifi_info(card->ospriv, "Failed to read UNIFI_SDIO_FUNCTION_NUM\n");
+ card->function = 1;
+ } else {
+ card->function = t;
+ }
+
+ /* Get the SDIO IO BLOCK SIZE from the SDIO driver. */
+ r = unifi_sdio_get_info(card->sdio_if, UNIFI_SDIO_IO_BLOCK_SIZE, &t);
+ if (r) {
+ unifi_info(card->ospriv, "Failed to read UNIFI_SDIO_IO_BLOCK_SIZE\n");
+ card->sdio_io_block_size = UNIFI_IO_BLOCK_SIZE;
+ } else {
+ card->sdio_io_block_size = t;
+ }
+ /*
+ * Setup the chip helper so that we can access the regisers (and
+ * also tell what sub-type of HIP we shold use).
+ */
+ card->helper = ChipHelper_GetVersionSdio(card->chip_id);
+
+ unifi_info(card->ospriv, "Chip ID 0x%02X Function %u Block Size %u Name %s(%s)\n",
+ card->chip_id, card->function, card->sdio_io_block_size,
+ ChipHelper_MarketingName(card->helper),
+ ChipHelper_FriendlyName(card->helper));
+
+ return 0;
+
+} /* unifi_identify_hw() */
+
+
+static int
+unifi_prepare_hw(card_t *card)
+{
+ uint16 ver;
+ int r;
+ unsigned long gbl_chip_version;
+
+ r = unifi_identify_hw(card);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to identify hw\n");
+ return r;
+ }
+
+ /*
+ * Chip must be a awake or blocks that are asleep may not get
+ * reset. We can only do this after we have read the chip_id.
+ */
+ r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
+ if (r == -ENODEV) return r;
+
+ /*
+ * The WLAN function must be enabled to access MAILBOX2 and DEBUG_RST
+ * registers.
+ */
+ r = unifi_sdio_enable(card->sdio_if);
+ if (r == -ENODEV) return r;
+ if (r) {
+ /* Can't enable WLAN function. Try resetting the SDIO block. */
+ unifi_error(card->ospriv, "Failed to re-enable function %d.\n", card->function);
+ return r;
+ }
+
+ /*
+ * Poke some registers to make sure the PLL has started,
+ * otherwise memory accesses are likely to fail.
+ */
+ bootstrap_chip_hw(card);
+
+ gbl_chip_version = ChipHelper_GBL_CHIP_VERSION(card->helper);
+
+ /* Try to read the chip version from register. */
+ if (gbl_chip_version != 0) {
+ r = unifi_read_direct16(card, gbl_chip_version * 2, &ver);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read GBL_CHIP_VERSION\n");
+ return r;
+ }
+ card->chip_version = ver;
+ } else {
+ unifi_info(card->ospriv, "Unknown Chip ID, cannot locate GBL_CHIP_VERSION\n");
+ }
+ unifi_info(card->ospriv, "Chip Version 0x%04X\n", card->chip_version);
+
+ return 0;
+} /* unifi_prepare_hw() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_reset_hardware
+ *
+ * Execute the UniFi reset sequence.
+ *
+ * Note: This may fail if the chip is going TORPID so retry at
+ * least once.
+ *
+ * Arguments:
+ * reset_type 1 for a cold reset, 2 for a warm reset
+ *
+ * Returns:
+ * 0 on success, error otherwise.
+ *
+ * Notes:
+ * Some platforms (e.g. Windows Vista) do not allow access to registers
+ * that are necessary for a software reset. In this case,
+ * #define DONT_USE_SOFTWARE_RESETS to allow only hardware resets.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_reset_hardware(card_t *card, enum unifi_reset_type reset_type)
+{
+ uint16 mbox2;
+ int r;
+
+ func_enter();
+
+ /*
+ * Errors returned from unifi_prepare_hw() are not critical at this point.
+ * If unifi_prepare_hw() fails, we skip software soft reset
+ * and try to hard reset UniFi.
+ */
+ r = unifi_prepare_hw(card);
+ if (r == -ENODEV) return r;
+
+ /*
+ * See if UniFi is able to process a soft reset.
+ * If firmware is loaded and alive, MAILBOX2 will be non-zero.
+ */
+ mbox2 = 0;
+#ifndef DONT_USE_SOFTWARE_RESETS
+ if (r == 0) {
+ r = unifi_read_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, &mbox2);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read SHARED_MAILBOX2B\n");
+ return r;
+ }
+ if (mbox2 != 0) {
+ unifi_trace(card->ospriv, UDBG1, "Trying soft reset\n");
+ r = CardSoftReset(card, reset_type);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_trace(card->ospriv, UDBG1, "soft reset failed\n");
+ }
+ }
+ }
+#endif
+
+ if (r || (mbox2 == 0)) {
+ /*
+ * Can't make a software request for a reset, or software
+ * reset failed, so have to do a hard reset.
+ */
+ r = unifi_sdio_hard_reset(card->sdio_if);
+ if (r == 0) {
+ unifi_info(card->ospriv, "unifi_sdio_hard_reset succeeded on reseting UniFi\n");
+ r = unifi_prepare_hw(card);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "unifi_prepare_hw failed after hard reset\n");
+ }
+
+ func_exit();
+ return r;
+ }
+ if (r == -ENODEV) {
+ return r;
+ }
+
+#ifndef DONT_USE_SOFTWARE_RESETS
+ /* Falling back to software hard reset */
+ unifi_info(card->ospriv, "Falling back to software hard reset\n");
+ r = CardHardReset(card);
+#else
+ /* We have no other way to reset UniFi, return an error. */
+ unifi_error(card->ospriv, "Can't use software resets, reset failed\n");
+ r = -EIO;
+#endif
+ }
+
+ func_exit();
+
+ return r;
+} /* unifi_reset_hardware() */
+
+
+static int
+CardSoftReset(card_t *card, enum unifi_reset_type reset_type)
+{
+ uint16 mbox2;
+ int i, r;
+
+ /*
+ * Wait for UniFi to finish processing previous command.
+ */
+ mbox2 = 1;
+ for (i = 0; i < MAILBOX2_RESET_ATTEMPTS; i++) {
+ unifi_trace(card->ospriv, UDBG1, "waiting for mailbox, attempt %d\n", i);
+ r = unifi_read_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, &mbox2);
+ if (r) {
+ unifi_trace(card->ospriv, UDBG1, "Failed to read UniFi Mailbox2 register prior to reset request\n");
+ func_exit();
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG2, "mbox2 = 0x%04X\n", mbox2);
+
+ if (mbox2 == 0xFFFF) {
+ unifi_trace(card->ospriv, UDBG1, "MAILBOX2 ready (0x%04X) in ~ %u msecs\n",
+ mbox2, i * MAILBOX2_RESET_TIMEOUT);
+ break;
+ }
+
+ unifi_sleep_ms(card->ospriv, MAILBOX2_RESET_TIMEOUT);
+ }
+ if (i == MAILBOX2_RESET_ATTEMPTS) {
+ unifi_error(card->ospriv, "Timeout waiting for processing to complete before soft reset\n");
+ func_exit();
+ return -ETIMEDOUT;
+ }
+
+ /*
+ * Request the reset.
+ */
+ r = unifi_write_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, reset_type);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_trace(card->ospriv, UDBG1, "Failed to write reset request to UniFi\n");
+ func_exit();
+ return r;
+ }
+
+ /* Signal the UniFi that reset has been requested */
+ r = CardGenInt(card);
+ if (r) {
+ unifi_trace(card->ospriv, UDBG1, "Failed to write interrupt reg for soft reset request\n");
+ func_exit();
+ return r;
+ }
+
+ /*
+ * Wait for UniFi to finish processing the reset request.
+ */
+ r = card_wait_for_unifi_to_reset(card);
+ if (r) {
+ /* error message already printed */
+ func_exit();
+ return r;
+ }
+
+ func_exit();
+ return 0;
+
+} /* CardSoftReset() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardHardReset
+ *
+ * Issue hard reset to the hw
+ *
+ * Arguments:
+ * card Pointer to Card object
+ *
+ * Returns:
+ * 0 on success,
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * -ETIMEDOUT if a response was not seen in the expected time
+ * ---------------------------------------------------------------------------
+ */
+static int
+CardHardReset(card_t *card)
+{
+ int r;
+ uint32 ram_offset;
+ const struct chip_helper_reset_values *init_data;
+ unsigned int i, j, chunks;
+
+ /* Clear cache of page registers */
+ card->proc_select = (unsigned long)(-1);
+ card->dmem_page = (unsigned long)(-1);
+ card->pmem_page = (unsigned long)(-1);
+
+ /*
+ * We need to have a valid card->helper before we use software hard reset.
+ * If unifi_identify_hw() fails to get the card ID, it probably means
+ * that there is no way to talk to the h/w.
+ */
+ r = unifi_identify_hw(card);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "CardHardReset failed to identify h/w\n");
+ return r;
+ }
+
+ /* Search for some reset code. */
+ chunks = ChipHelper_HostResetSequence(card->helper, &init_data);
+ if (chunks != 0) {
+
+ unifi_trace(card->ospriv, UDBG1, "Hard reset (Code download)\n");
+
+ if (card->host_state == UNIFI_HOST_STATE_TORPID) {
+ /* Write the new state to UniFi. */
+ r = sdio_write_f0(card, SDIO_IO_ABORT, UNIFI_HOST_STATE_DROWSY);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write to UniFi IOABORT register\n");
+ }
+
+ unifi_sleep_ms(card->ospriv, 5);
+ }
+
+ r = card_stop_processor(card, UNIFI_PROC_BOTH);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to stop processors\n");
+ return r;
+ }
+
+ /* Select MAC */
+ r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write to Proc Select register\n");
+ return r;
+ }
+
+ /* Write the chunks */
+ for (j = 0; j < chunks; j++, init_data++) {
+ for (i = 0; i < init_data->len; i++) {
+ r = unifi_write16(card, init_data->gp_address + (i * 2), init_data->data[i]);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write to Reset Program\n");
+ return r;
+ }
+ }
+ }
+
+ ram_offset = ChipHelper_PROGRAM_MEMORY_RAM_OFFSET(card->helper);
+
+ /* Write PCL and PCH */
+ r = unifi_write_direct16(card, ChipHelper_XAP_PCL(card->helper) * 2, (uint16)(ram_offset & 0xffff));
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to set PCL\n");
+ return r;
+ }
+ r = unifi_write_direct8(card, ChipHelper_XAP_PCH(card->helper) * 2, (uint8)(ram_offset >> 16));
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to set PCH\n");
+ return r;
+ }
+
+ r = card_start_processor(card, UNIFI_PROC_MAC);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to start MAC processor\n");
+ return r;
+ }
+ } else {
+ if (card->chip_id > SDIO_CARD_ID_UNIFI_2) {
+ /*
+ * This resets onyl function 1, so should be used in
+ * preference to the method below (CSR_FUNC_EN)
+ */
+ unifi_trace(card->ospriv, UDBG1, "Hard reset (IO_ENABLE)\n");
+
+ r = unifi_sdio_disable(card->sdio_if);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_warning(card->ospriv, "SDIO error writing IO_ENABLE: %d\n", r);
+ unifi_trace(card->ospriv, UDBG1, "Hard reset (CSR_FUNC_EN)\n");
+
+ r = sdio_write_f0(card, SDIO_CSR_FUNC_EN, 0);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_warning(card->ospriv, "SDIO error writing SDIO_CSR_FUNC_EN: %d\n", r);
+ unifi_trace(card->ospriv, UDBG1, "Hard reset (DBG_RESET)\n");
+
+ r = unifi_sdio_writeb(card->sdio_if, card->function,
+ ChipHelper_DBG_RESET(card->helper) * 2, 1);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_warning(card->ospriv, "SDIO error writing DBG_RESET: %d\n", r);
+ }
+ }
+ }
+ } else {
+ unifi_trace(card->ospriv, UDBG1, "Hard reset (DBG_RESET)\n");
+
+ /*
+ * This register write will fail. The debug reset resets
+ * parts of the Function 0 sections of the chip, and
+ * therefore the response cannot be sent back to the
+ * host.
+ */
+ r = unifi_sdio_writeb(card->sdio_if, card->function,
+ ChipHelper_DBG_RESET(card->helper) * 2, 1);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_warning(card->ospriv, "SDIO error writing DBG_RESET: %d\n", r);
+ }
+ }
+
+ /* Delay here to let the reset take affect. */
+ unifi_sleep_ms(card->ospriv, RESET_SETTLE_DELAY);
+ }
+
+ return card_wait_for_unifi_to_reset(card);
+} /* CardHardReset() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * CardGenInt
+ *
+ * Prod the card.
+ * This function causes an internal interrupt to be raised in the
+ * UniFi chip. It is used to signal the firmware that some action has
+ * been completed.
+ * The UniFi Host Interface asks that the value used increments for
+ * debugging purposes.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ *
+ * Returns:
+ * 0 on success,
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * -ETIMEDOUT if a response was not seen in the expected time
+ * ---------------------------------------------------------------------------
+ */
+int
+CardGenInt(card_t *card)
+{
+ int r;
+
+ func_enter();
+
+ if (card->chip_id > SDIO_CARD_ID_UNIFI_2) {
+ r = sdio_write_f0(card, SDIO_CSR_FROM_HOST_SCRATCH0,
+ (uint8)card->unifi_interrupt_seq);
+ } else {
+ r = unifi_write_direct8(card,
+ ChipHelper_SHARED_IO_INTERRUPT(card->helper) * 2,
+ (uint8)card->unifi_interrupt_seq);
+ }
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error writing UNIFI_SHARED_IO_INTERRUPT: %d\n", r);
+ func_exit();
+ return r;
+ }
+
+ card->unifi_interrupt_seq++;
+
+ func_exit();
+ return 0;
+} /* CardGenInt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardEnableInt
+ *
+ * Enable the outgoing SDIO interrupt from UniFi to the host.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ *
+ * Returns:
+ * 0 on success,
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * ---------------------------------------------------------------------------
+ */
+int
+CardEnableInt(card_t *card)
+{
+ int r;
+ uint8 int_enable;
+
+ r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
+ return r;
+ }
+
+ int_enable |= (1 << card->function) | UNIFI_SD_INT_ENABLE_IENM;
+
+ r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n");
+ return r;
+ }
+
+ return 0;
+} /* CardEnableInt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardDisableInt
+ *
+ * Disable the outgoing SDIO interrupt from UniFi to the host.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ *
+ * Returns:
+ * 0 on success,
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * ---------------------------------------------------------------------------
+ */
+int
+CardDisableInt(card_t *card)
+{
+ int r;
+ uint8 int_enable;
+
+ r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
+ return r;
+ }
+
+ int_enable &= ~(1 << card->function);
+
+ r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n");
+ return r;
+ }
+
+ return 0;
+} /* CardDisableInt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardPendingInt
+ *
+ * Determine whether UniFi is currently asserting the SDIO interrupt
+ * request.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ *
+ * Returns:
+ * 1 - There is a pending interrupt
+ * 0 - There is not a pending interrupt
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * ---------------------------------------------------------------------------
+ */
+int
+CardPendingInt(card_t *card)
+{
+ int r;
+ unsigned char pending;
+
+ r = sdio_read_f0(card, SDIO_INT_PENDING, &pending);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error reading SDIO_INT_PENDING\n");
+ return r;
+ }
+
+ return (pending & (1 << card->function)) ? 1 : 0;
+} /* CardPendingInt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardClearInt
+ *
+ * Clear the UniFi SDIO interrupt request.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ *
+ * Returns:
+ * 0 if pending interrupt was cleared, or no pending interrupt.
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * ---------------------------------------------------------------------------
+ */
+int
+CardClearInt(card_t *card)
+{
+ int r;
+ if (card->chip_id > SDIO_CARD_ID_UNIFI_2) {
+
+ /* CardPendingInt() returns 1, if there is a pending interrupt */
+ r = CardPendingInt(card);
+ if (r != 1) {
+ return r;
+ }
+
+ r = sdio_write_f0(card, SDIO_CSR_HOST_INT_CLEAR, 1);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error writing SDIO_CSR_HOST_INT_CLEAR\n");
+ }
+ } else {
+ r = unifi_write_direct8(card, ChipHelper_SDIO_HOST_INT(card->helper) * 2, 0);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error writing UNIFI_SDIO_HOST_INT\n");
+ }
+ }
+
+ return r;
+} /* CardClearInt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardIntEnabled
+ *
+ * Determine whether UniFi is currently asserting the SDIO interrupt
+ * request.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ *
+ * Returns:
+ * 1 interrupts are enabled
+ * 0 interrupts are disabled
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * ---------------------------------------------------------------------------
+ */
+int
+CardIntEnabled(card_t *card)
+{
+ int r;
+ unsigned char int_enable;
+
+ r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
+ return r;
+ }
+
+ return (int_enable & (1 << card->function)) ? 1 : 0;
+} /* CardIntEnabled() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * CardWriteBulkData
+ *
+ * Claim a bulk data slot and copy data to it.
+ *
+ * Arguments:
+ * card Pointer to the card context struct
+ * bulkdata Pointer to bulk data structure that
+ * describes the data to copy to slot.
+ *
+ * Returns:
+ * slot number or -1 if no slot was available.
+ * ---------------------------------------------------------------------------
+ */
+int
+CardWriteBulkData(card_t *card, bulk_data_desc_t* bulkdata)
+{
+ int slot;
+
+ func_enter();
+
+ slot = CardGetFromHostDataSlot(card, bulkdata->data_length);
+ if (slot < 0) {
+ func_exit();
+ return slot;
+ }
+
+ /* Do not copy the data, just store the information to them */
+ card->from_host_data[slot].os_data_ptr = bulkdata->os_data_ptr;
+ card->from_host_data[slot].os_net_buf_ptr = bulkdata->os_net_buf_ptr;
+ card->from_host_data[slot].data_length = bulkdata->data_length;
+ card->from_host_data[slot].net_buf_length = bulkdata->net_buf_length;
+
+ /* Pass the free responsibility to the lower layer. */
+ unifi_init_bulk_data(bulkdata);
+
+ func_exit();
+
+ return slot;
+} /* CardWriteBulkData() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_find_data_slot
+ *
+ * Dereference references to bulk data slots into pointers to real data.
+ *
+ * Arguments:
+ * card Pointer to the card struct.
+ * slot Slot number from a signal structure
+ *
+ * Returns:
+ * Pointer to entry in bulk_data_slot array.
+ * ---------------------------------------------------------------------------
+ */
+bulk_data_desc_t *
+card_find_data_slot(card_t *card, int slot)
+{
+ int sn;
+ bulk_data_desc_t *bd;
+
+ sn = slot & 0x7FFF;
+
+ /* ?? check sanity of slot number ?? */
+
+ if (slot & SLOT_DIR_TO_HOST) {
+ bd = &card->to_host_data[sn];
+ } else {
+ bd = &card->from_host_data[sn];
+ }
+
+ return bd;
+} /* card_find_data_slot() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * firmware_present_in_flash
+ *
+ * Probe for external Flash that looks like it might contain firmware.
+ *
+ * If Flash is not present, reads always return 0x0008.
+ * If Flash is present, but empty, reads return 0xFFFF.
+ * Anything else is considered to be firmware.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * 1 firmware is present
+ * 0 firmware is not present
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred,
+ * ---------------------------------------------------------------------------
+ */
+static int
+firmware_present_in_flash(card_t *card)
+{
+ int r;
+ int present = 1;
+ uint16 m1, m5;
+
+ if (ChipHelper_HasRom(card->helper))
+ return 1;
+ if (!ChipHelper_HasFlash(card->helper))
+ return 0;
+
+ /*
+ * Examine the Flash locations that are the power-on default reset
+ * vectors of the XAP processors.
+ * These are words 1 and 5 in Flash.
+ */
+ r = unifi_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 2), &m1);
+ if (r == -ENODEV) return r;
+
+ if (r) {
+ /* Error reading flash, probably means it is not attached. Ignore */
+ unifi_error(card->ospriv, "SDIO error checking 1st flash location, assume no flash\n");
+ return 0; /* No flash - needs download */
+ }
+
+ r = unifi_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 10), &m5);
+ if (r == -ENODEV) return r;
+
+ if (r) {
+ /* Error reading flash, probably means it is not attached. Ignore */
+ unifi_error(card->ospriv, "SDIO error checking 2st flash location, assume no flash\n");
+ return 0; /* No flash - needs download */
+ }
+
+
+ if ((m1 == 0x0008) || (m1 == 0xFFFF) ||
+ (m1 == 0x0004) || (m5 == 0x0004) ||
+ (m5 == 0x0008) || (m5 == 0xFFFF))
+ {
+ present = 0;
+ }
+
+ return present;
+} /* firmware_present_in_flash() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * bootstrap_chip_hw
+ *
+ * Perform chip specific magic to "Get It Working" TM. This will
+ * increase speed of PLLs in analogue and maybe enable some
+ * on-chip regulators.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+bootstrap_chip_hw(card_t *card)
+{
+ const struct chip_helper_init_values *vals;
+ unsigned int i, len;
+ unsigned char b0, b1;
+ void *sdio = card->sdio_if;
+ int r;
+
+ len = ChipHelper_ClockStartupSequence(card->helper, &vals);
+ if (len != 0) {
+ for (i=0; i<len; i++) {
+
+ b1 = (vals[i].value >> 8) & 0xFF;
+ r = unifi_sdio_writeb(sdio, card->function, (vals[i].addr * 2) + 1, b1);
+ if (r) {
+ unifi_warning(card->ospriv, "Failed to write bootstrap value %d\n", i);
+ /* Might not be fatal */
+ }
+
+ b0 = vals[i].value & 0xFF;
+ r = unifi_sdio_writeb(sdio, card->function, vals[i].addr * 2, b0);
+ if (r) {
+ unifi_warning(card->ospriv, "Failed to write bootstrap value %d\n", i);
+ /* Might not be fatal */
+ }
+
+ unifi_sleep_ms(card->ospriv, 1);
+ }
+ }
+
+} /* bootstrap_chip_hw() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_stop_processor
+ *
+ * Stop the UniFi XAP processors.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * which One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int
+card_stop_processor(card_t *card, int which)
+{
+ int r = 0;
+ uint8 status;
+ int retry = 100;
+
+ while (retry--) {
+ /* Select both XAPs */
+ r = unifi_set_proc_select(card, which);
+ if (r) break;
+
+ /* Stop processors */
+ r = unifi_write_direct16(card, ChipHelper_DBG_EMU_CMD(card->helper) * 2, 2);
+ if (r) break;
+
+ /* Read status */
+ r = unifi_read_direct8(card, ChipHelper_DBG_HOST_STOP_STATUS(card->helper) * 2, &status);
+ if (r) break;
+
+ if ((status & 1) == 1) {
+ /* Success! */
+ return 0;
+ }
+
+ /* Processors didn't stop, try again */
+ }
+
+ if (r) {
+ /* An SDIO error occurred */
+ unifi_error(card->ospriv, "Failed to stop processors: SDIO error\n");
+ } else {
+ /* If we reach here, we didn't the status in time. */
+ unifi_error(card->ospriv, "Failed to stop processors: timeout waiting for stopped status\n");
+ r = -ETIMEDOUT;
+ }
+
+ return r;
+} /* card_stop_processor() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * card_start_processor
+ *
+ * Start the UniFi XAP processors.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * which One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH
+ *
+ * Returns:
+ * None
+ * ---------------------------------------------------------------------------
+ */
+int
+card_start_processor(card_t *card, int which)
+{
+ int r;
+
+ /* Select both XAPs */
+ r = unifi_set_proc_select(card, which);
+ if (r) {
+ unifi_error(card->ospriv, "unifi_set_proc_select failed: %d.\n", r);
+ return r;
+ }
+
+
+ r = unifi_write_direct8(card, ChipHelper_DBG_EMU_CMD(card->helper) * 2, 8);
+ if (r) return r;
+
+ r = unifi_write_direct8(card, ChipHelper_DBG_EMU_CMD(card->helper) * 2, 0);
+ if (r) return r;
+
+ return 0;
+
+} /* card_start_processor() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_set_host_state
+ *
+ * Set the host deep-sleep state.
+ *
+ * If transitioning to TORPID, the SDIO driver will be notified
+ * that the SD bus will be unused (idle) and conversely, when
+ * transitioning from TORPID that the bus will be used (active).
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * state New deep-sleep state.
+ *
+ * Returns:
+ * 0 on success
+ * -ENODEV if the card was ejected
+ * -EIO if an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_set_host_state(card_t *card, enum unifi_host_state state)
+{
+ int r = 0;
+ static const char *const states[] = {
+ "AWAKE", "DROWSY", "TORPID"
+ };
+ static const uint8 state_csr_host_wakeup[] = {
+ 1, 3, 0
+ };
+ static const uint8 state_io_abort[] = {
+ 0, 2, 3
+ };
+
+ unifi_trace(card->ospriv, UDBG4, "State %s to %s\n", states[card->host_state], states[state]);
+
+ if (card->host_state == UNIFI_HOST_STATE_TORPID) {
+ unifi_sdio_active(card->sdio_if);
+ }
+
+ /* Write the new state to UniFi. */
+ if (card->chip_id > SDIO_CARD_ID_UNIFI_2) {
+ r = sdio_write_f0(card, SDIO_CSR_HOST_WAKEUP,
+ (card->function << 4) | state_csr_host_wakeup[state]);
+ } else {
+ r = sdio_write_f0(card, SDIO_IO_ABORT, state_io_abort[state]);
+ }
+
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write UniFi deep sleep state\n");
+ } else {
+ /*
+ * Cache the current state in the card structure to avoid
+ * unnecessary SDIO reads.
+ */
+ card->host_state = state;
+
+ if (state == UNIFI_HOST_STATE_TORPID) {
+ unifi_sdio_idle(card->sdio_if);
+ }
+ }
+
+ return r;
+
+} /* unifi_set_host_state() */
+
+
+void unifi_card_info(card_t *card, card_info_t *card_info)
+{
+ card_info->chip_id = (uint16)card->chip_id;
+ card_info->chip_version = (uint16)card->chip_version;
+ card_info->fw_build = card->build_id;
+ card_info->fw_hip_version = card->config_data.version;
+ card_info->sdio_block_size = card->sdio_io_block_size;
+} /* unifi_card_info() */
+
+
+int unifi_check_io_status(card_t *card)
+{
+ unsigned char io_en;
+ int r;
+
+ r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_en);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read SDIO_IO_ENABLE to check for spontaneous reset\n");
+ return r;
+ }
+
+ if ((io_en & (1 << card->function)) == 0)
+ {
+ unifi_error(card->ospriv, "UniFi has spontaneously reset.\n");
+ return 1;
+ }
+ else
+ {
+ unifi_info(card->ospriv, "UniFi function %d is enabled.\n", card->function);
+ }
+
+ return 0;
+} /* unifi_check_io_status() */
+
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.h b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.h
new file mode 100644
index 0000000..53e300f
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio.h
@@ -0,0 +1,558 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: card_sdio.h
+ *
+ * PURPOSE:
+ * Internal header for Card API for SDIO.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __CARD_SDIO_H__
+#define __CARD_SDIO_H__
+
+#include "driver/unifi.h"
+#include "driver/unifi_udi.h"
+#include "unifihw.h"
+#include "driver/unifiversion.h"
+#include "ta_sampling.h"
+#include "xbv.h"
+#include "chiphelper.h"
+
+
+/*
+ *
+ * Configuration items.
+ * Which of these should go in a platform unifi_config.h file?
+ *
+ */
+
+/* The number of traffic queues to provide. This is 4 for WME/WMM. */
+#define UNIFI_WME_NO_OF_QS 4
+
+/*
+ * When the traffic queues contain more signals than there is space for on
+ * UniFi, a limiting algorithm comes into play.
+ * If a traffic queue has enough slots free to buffer more traffic from the
+ * network stack, then the following check is applied. The number of free
+ * slots is RESUME_XMIT_THRESHOLD.
+ *
+ * If more than MAX_PENDING_SIGNALS_PER_Q have already been sent to UniFi,
+ * then we move to the next queue.
+ */
+#define RESUME_XMIT_THRESHOLD 4
+#define MAX_PENDING_SIGNALS_PER_Q 10
+
+
+/*
+ * When reading signals from UniFi, the host processes pending all signals
+ * and then acknowledges them together in a single write to update the
+ * to-host-chunks-read location.
+ * When there is more than one bulk data transfer (e.g. one received data
+ * packet and a request for the payload data of a transmitted packet), the
+ * update can be delayed significantly. This ties up resources on chip.
+ *
+ * To remedy this problem, to-host-chunks-read is updated after processing
+ * a signal if TO_HOST_FLUSH_THRESHOLD bytes of bulk data have been
+ * transferred since the last update.
+ */
+#define TO_HOST_FLUSH_THRESHOLD (500*5)
+
+
+
+
+
+
+/* SDIO Card Common Control Registers */
+#define SDIO_CCCR_SDIO_REVISION (0x00)
+#define SDIO_SD_SPEC_REVISION (0x01)
+#define SDIO_IO_ENABLE (0x02)
+#define SDIO_IO_READY (0x03)
+#define SDIO_INT_ENABLE (0x04)
+#define SDIO_INT_PENDING (0x05)
+#define SDIO_IO_ABORT (0x06)
+#define SDIO_BUS_IFACE_CONTROL (0x07)
+#define SDIO_CARD_CAPABILOTY (0x08)
+#define SDIO_COMMON_CIS_POINTER (0x09)
+#define SDIO_BUS_SUSPEND (0x0C)
+#define SDIO_FUNCTION_SELECT (0x0D)
+#define SDIO_EXEC_FLAGS (0x0E)
+#define SDIO_READY_FLAGS (0x0F)
+#define SDIO_FN0_BLOCK_SIZE (0x10)
+#define SDIO_POWER_CONTROL (0x12)
+#define SDIO_VENDOR_START (0xF0)
+
+#define SDIO_CSR_HOST_WAKEUP (0xf0)
+#define SDIO_CSR_HOST_INT_CLEAR (0xf1)
+#define SDIO_CSR_FROM_HOST_SCRATCH0 (0xf2)
+#define SDIO_CSR_FROM_HOST_SCRATCH1 (0xf3)
+#define SDIO_CSR_TO_HOST_SCRATCH0 (0xf4)
+#define SDIO_CSR_TO_HOST_SCRATCH1 (0xf5)
+#define SDIO_CSR_FUNC_EN (0xf6)
+#define SDIO_CSR_CSPI_MODE (0xf7)
+#define SDIO_CSR_CSPI_STATUS (0xf8)
+#define SDIO_CSR_CSPI_PADDING (0xf9)
+
+
+
+#define UNIFI_SD_INT_ENABLE_IENM 0x0001 /* Master INT Enable */
+
+
+
+/*
+ * Structure to hold configuration information read from UniFi.
+ */
+typedef struct {
+
+ /*
+ * The version of the SDIO signal queues and bulk data pools
+ * configuration structure. The MSB is the major version number, used to
+ * indicate incompatible changes. The LSB gives the minor revision number,
+ * used to indicate changes that maintain backwards compatibility.
+ */
+ uint16 version;
+
+ /*
+ * offset from the start of the shared data memory to the SD IO
+ * control structure.
+ */
+ uint16 sdio_ctrl_offset;
+
+ /* Buffer handle of the from-host signal queue */
+ uint16 fromhost_sigbuf_handle;
+
+ /* Buffer handle of the to-host signal queue */
+ uint16 tohost_sigbuf_handle;
+
+ /*
+ * Maximum number of signal primitive or bulk data command fragments that may be
+ * pending in the to-hw signal queue.
+ */
+ uint16 num_fromhost_sig_frags;
+
+ /*
+ * Number of signal primitive or bulk data command fragments that must be pending
+ * in the to-host signal queue before the host will generate an interrupt
+ * to indicate that it has read a signal. This will usually be the total
+ * capacity of the to-host signal buffer less the size of the largest signal
+ * primitive divided by the signal primitive fragment size, but may be set
+ * to 1 to request interrupts every time that the host read a signal.
+ * Note that the hw may place more signals in the to-host signal queue
+ * than indicated by this field.
+ */
+ uint16 num_tohost_sig_frags;
+
+ /*
+ * Number of to-hw bulk data slots. Slots are numbered from 0 (zero) to
+ * one less than the value in this field
+ */
+ uint16 num_fromhost_data_slots;
+
+ /*
+ * Number of frm-hw bulk data slots. Slots are numbered from 0 (zero) to
+ * one less than the value in this field
+ */
+ uint16 num_tohost_data_slots;
+
+ /*
+ * Size of the bulk data slots (2 octets)
+ * The size of the bulk data slots in octets. This will usually be
+ * the size of the largest MSDU. The value should always be even.
+ */
+ uint16 data_slot_size;
+
+ /*
+ * Indicates that the host has finished the initialisation sequence.
+ * Initialised to 0x0000 by the firmware, and set to 0x0001 by us.
+ */
+ uint16 initialised;
+
+ /* Added by protocol version 0x0001 */
+ uint32 overlay_size;
+
+ /* Added by protocol version 0x0300 */
+ uint16 data_slot_round;
+ uint16 sig_frag_size;
+
+ /* Added by protocol version 0x0500 */
+ uint16 tohost_signal_padding;
+
+} sdio_config_data_t;
+
+/*
+ * These values may change with versions of the Host Interface Protocol.
+ */
+/*
+ * Size of config info block pointed to by the CSR_SLT_SDIO_SLOT_CONFIG
+ * entry in the f/w symbol table
+ */
+#define SDIO_CONFIG_DATA_SIZE 30
+
+/* Offset of the INIT flag in the config info block. */
+#define SDIO_INIT_FLAG_OFFSET 0x12
+#define SDIO_TO_HOST_SIG_PADDING_OFFSET 0x1C
+
+
+
+/* Structure for a bulk data transfer command */
+typedef struct {
+ uint16 cmd_and_len; /* bits 12-15 cmd, bits 0-11 len */
+ uint16 data_slot; /* slot number, perhaps OR'd with SLOT_DIR_TO_HOST */
+ uint16 offset;
+ uint16 buffer_handle;
+} bulk_data_cmd_t;
+
+
+/* Bulk Data signal command values */
+#define SDIO_CMD_SIGNAL 0x00
+#define SDIO_CMD_TO_HOST_TRANSFER 0x01
+#define SDIO_CMD_TO_HOST_TRANSFER_ACK 0x02 /*deprecated*/
+#define SDIO_CMD_FROM_HOST_TRANSFER 0x03
+#define SDIO_CMD_FROM_HOST_TRANSFER_ACK 0x04 /*deprecated*/
+#define SDIO_CMD_CLEAR_SLOT 0x05
+#define SDIO_CMD_OVERLAY_TRANSFER 0x06
+#define SDIO_CMD_OVERLAY_TRANSFER_ACK 0x07 /*deprecated*/
+#define SDIO_CMD_FROM_HOST_AND_CLEAR 0x08
+#define SDIO_CMD_PADDING 0x0f
+
+#define SLOT_DIR_TO_HOST 0x8000
+
+
+
+static INLINE void unifi_init_bulk_data(bulk_data_desc_t *bulk_data_slot)
+{
+ bulk_data_slot->os_data_ptr = NULL;
+ bulk_data_slot->data_length = 0;
+ bulk_data_slot->os_net_buf_ptr = NULL;
+ bulk_data_slot->net_buf_length = 0;
+}
+
+/*
+ * Structure to contain a SIGNAL datagram.
+ * This is used to build signal queues between the main driver and the
+ * i/o thread.
+ * The fields are:
+ * sigbuf Contains the HIP signal is wire-format (i.e. packed,
+ * little-endian)
+ * bulkdata Contains a copy of any associated bulk data
+ * signal_length The size of the signal in the sigbuf
+ */
+typedef struct card_signal {
+ unsigned char sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
+
+ /* Length of the SIGNAL inside sigbuf */
+ unsigned int signal_length;
+
+ bulk_data_desc_t bulkdata[UNIFI_MAX_DATA_REFERENCES];
+
+} card_signal_t;
+
+
+
+/*
+ * Control structure for a generic ring buffer.
+ */
+typedef struct {
+ card_signal_t *q_body;
+
+ /* Num elements in queue (capacity is one less than this!) */
+ unsigned int q_length;
+
+ unsigned int q_wr_ptr;
+ unsigned int q_rd_ptr;
+
+ char name[16];
+} q_t;
+
+
+/* These are type-safe and don't write incorrect values to the
+ * structure. */
+static INLINE unsigned int q_slots_used(const q_t *q)
+{
+ int t = q->q_wr_ptr - q->q_rd_ptr;
+ if (t < 0)
+ {
+ t += q->q_length;
+ ASSERT(t > 0);
+ }
+ return (unsigned int)t;
+}
+static INLINE unsigned int q_slots_free(const q_t *q)
+{
+ return (q->q_length - q_slots_used(q)) - 1;
+}
+static INLINE card_signal_t *q_slot_data(const q_t *q, int slot)
+{
+ return q->q_body + slot;
+}
+static INLINE unsigned int q_next_r_slot(const q_t *q)
+{
+ return q->q_rd_ptr;
+}
+static INLINE unsigned int q_next_w_slot(const q_t *q)
+{
+ return q->q_wr_ptr;
+}
+static INLINE unsigned int q_wrap(const q_t *q, unsigned int x)
+{
+ if (x >= q->q_length)
+ return x % q->q_length;
+ else
+ return x;
+}
+static INLINE void q_inc_r(q_t *q)
+{
+ q->q_rd_ptr = q_wrap(q, q->q_rd_ptr + 1);
+}
+static INLINE void q_inc_w(q_t *q)
+{
+ q->q_wr_ptr = q_wrap(q, q->q_wr_ptr + 1);
+}
+
+
+
+enum unifi_host_state {
+ UNIFI_HOST_STATE_AWAKE = 0,
+ UNIFI_HOST_STATE_DROWSY = 1,
+ UNIFI_HOST_STATE_TORPID = 2
+};
+
+
+/*
+ * Structure describing a UniFi SDIO card.
+ */
+struct card {
+
+ /*
+ * Back pointer for the higher level OS code. This is passed as
+ * an argument to callbacks (e.g. for received data and indications).
+ */
+ void *ospriv;
+
+
+ /* Info read from Symbol Table during probe */
+ uint32 build_id;
+ char build_id_string[128];
+
+ /* Retrieve from SDIO driver. */
+ unsigned int chip_id;
+
+ /* Read from GBL_CHIP_VERSION. */
+ unsigned int chip_version;
+
+ /* From the SDIO driver (probably 1) */
+ unsigned int function;
+
+ /* This is sused to get the register addresses and things. */
+ ChipDescript *helper;
+
+ /* What state is the hardware currently in? */
+ /*HERE*//*enum hw_state hw_state;*/
+
+
+ /*
+ * Bit mask of PIOs for the loader to waggle during download.
+ * We assume these are connected to LEDs. The main firmware gets
+ * the mask from a MIB entry.
+ */
+ int loader_led_mask;
+
+ /*
+ * Support for flow control. When the from-host queue of signals
+ * is full, we ask the host upper layer to stop sending packets. When
+ * the queue drains we tell it that it can send packets again.
+ * We use this flag to remember the current state.
+ */
+ int paused;
+
+
+
+ /* UDI callback for logging UniFi interactions */
+ udi_func_t udi_hook;
+
+ unsigned char bh_reason_host;
+ unsigned char bh_reason_unifi;
+
+ /*
+ * Current host state (copy of value in IOABORT register and
+ * spinlock to protect it.
+ */
+ enum unifi_host_state host_state;
+
+ enum unifi_low_power_mode low_power_mode;
+ enum unifi_periodic_wake_mode periodic_wake_mode;
+
+ /*
+ * Ring buffer of signal structs for a queue of data packets from
+ * the host.
+ * The queue is empty when fh_data_q_num_rd == fh_data_q_num_wr.
+ * To add a packet to the queue, copy it to index given by
+ * (fh_data_q_num_wr%UNIFI_SOFT_Q_LENGTH) and advance fh_data_q_num_wr.
+ * To take a packet from the queue, copy data from index given by
+ * (fh_data_q_num_rd%UNIFI_SOFT_Q_LENGTH) and advance fh_data_q_num_rd.
+ * fh_data_q_num_rd and fh_data_q_num_rd are both modulo 256.
+ */
+ card_signal_t fh_command_q_body[UNIFI_SOFT_COMMAND_Q_LENGTH];
+ q_t fh_command_queue;
+
+ card_signal_t fh_traffic_q_body[UNIFI_WME_NO_OF_QS][UNIFI_SOFT_TRAFFIC_Q_LENGTH];
+ q_t fh_traffic_queue[UNIFI_WME_NO_OF_QS];
+
+ unsigned int fh_pending_unitdata_req[UNIFI_WME_NO_OF_QS];
+
+ /*
+ * Signal counts from UniFi SDIO Control Data Structure.
+ * These are cached and synchronised with the UniFi before and after
+ * a batch of operations.
+ *
+ * These are the modulo-256 count of signals written to or read from UniFi
+ * The value is incremented for every signal.
+ */
+ int from_host_signals_w;
+ int from_host_signals_r;
+ int to_host_signals_r;
+ int to_host_signals_w;
+
+
+ /* Should specify buffer size as a number of signals */
+ /*
+ * Enough for 10 th and 10 fh data slots:
+ * 1 * 10 * 8 = 80
+ * 2 * 10 * 8 = 160
+ */
+#define UNIFI_FH_BUF_SIZE 1024
+ struct sigbuf {
+ unsigned char *buf; /* buffer area */
+ unsigned char *ptr; /* current pos */
+ unsigned int count; /* signal count */
+ unsigned int bufsize;
+ } fh_buffer;
+ struct sigbuf th_buffer;
+
+
+ /*
+ * Field to use for the incrementing value to write to the UniFi
+ * SHARED_IO_INTERRUPT register.
+ * Flag to say we need to generate an interrupt at end of processing.
+ */
+ unsigned long unifi_interrupt_seq;
+ unsigned char generate_interrupt;
+
+
+ /* Pointers to the bulk data slots */
+ bulk_data_desc_t *from_host_data;
+ bulk_data_desc_t *to_host_data;
+
+
+ /*
+ * Index of the next (hopefully) free data slot.
+ * This is an optimisation that starts searching at a more likely point
+ * than the beginning.
+ */
+ int from_host_data_head;
+
+
+ /*
+ * SDIO specific fields
+ */
+
+ /* Interface pointer for the SDIO library */
+ void *sdio_if;
+
+ /* Copy of config_data struct from the card */
+ sdio_config_data_t config_data;
+
+ /* SDIO address of the Initialised flag and Control Data struct */
+ unsigned long init_flag_addr;
+ unsigned long sdio_ctrl_addr;
+
+ /* The last value written to the Shared Data Memory Page register */
+ unsigned long proc_select;
+ unsigned long dmem_page;
+ unsigned long pmem_page;
+
+ uint64 sdio_bytes_read;
+ uint64 sdio_bytes_written;
+
+ unsigned char memory_resources_allocated;
+
+ /* UniFi SDIO I/O Block size. */
+ uint32 sdio_io_block_size;
+
+ /* Read from the XBV */
+ struct FWOV fwov;
+
+
+ /* TA sampling */
+ ta_data_t ta_sampling;
+
+}; /* struct card */
+
+
+/* Reset types */
+enum unifi_reset_type {
+ UNIFI_COLD_RESET = 1,
+ UNIFI_WARM_RESET = 2
+};
+
+/*
+ * unifi_set_host_state() implements signalling for waking UniFi from
+ * deep sleep. The host indicates to UniFi that it is in one of three states:
+ * Torpid - host has nothing to send, UniFi can go to sleep.
+ * Drowsy - host has data to send to UniFi. UniFi will respond with an
+ * SDIO interrupt. When hosts responds it moves to Awake.
+ * Awake - host has data to transfer, UniFi must stay awake.
+ * When host has finished, it moves to Torpid.
+ */
+int unifi_set_host_state(card_t *card, enum unifi_host_state state);
+
+
+int card_read_signal_counts(card_t *card);
+bulk_data_desc_t *card_find_data_slot(card_t *card, int slot);
+
+
+int unifi_set_proc_select(card_t *card, int select);
+
+int unifi_read8(card_t *card, unsigned long unifi_addr, uint8 *pdata);
+int unifi_read16(card_t *card, unsigned long unifi_addr, uint16 *pdata);
+int unifi_read32(card_t *card, unsigned long unifi_addr, uint32 *pdata);
+int unifi_readn(card_t *card, unsigned long unifi_addr, void *pdata, int len);
+int unifi_readnz(card_t *card, unsigned long unifi_addr,
+ void *pdata, int len);
+
+int unifi_write8(card_t *card, unsigned long unifi_addr, uint8 data);
+int unifi_write16(card_t *card, unsigned long unifi_addr, uint16 data);
+int unifi_writen(card_t *card, unsigned long unifi_addr, void *pdata, int len);
+
+int unifi_bulk_rw(card_t *card, unsigned long handle,
+ void *pdata, unsigned int len, int direction);
+int unifi_bulk_rw_noretry(card_t *card, unsigned long handle,
+ void *pdata, unsigned int len, int direction);
+#define UNIFI_SDIO_READ 0
+#define UNIFI_SDIO_WRITE 1
+
+
+int unifi_read_direct8(card_t *card, unsigned long addr, uint8 *pdata);
+int unifi_read_direct16(card_t *card, unsigned long addr, uint16 *pdata);
+int unifi_read_direct32(card_t *card, unsigned long addr, uint32 *pdata);
+int unifi_read_directn(card_t *card, unsigned long addr, void *pdata, int len);
+
+int unifi_write_direct8(card_t *card, unsigned long addr, uint8 data);
+int unifi_write_direct16(card_t *card, unsigned long addr, uint16 data);
+int unifi_write_directn(card_t *card, unsigned long addr, void *pdata, int len);
+
+int sdio_read_f0(card_t *card, unsigned long addr, uint8 *pdata);
+int sdio_write_f0(card_t *card, unsigned long addr, uint8 data);
+
+
+/* For diagnostic use */
+void dump(void *mem, int len);
+void dump16(void *mem, int len);
+
+
+#endif /* __CARD_SDIO_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_intr.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_intr.c
new file mode 100644
index 0000000..fa3bd01
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_intr.c
@@ -0,0 +1,2262 @@
+#undef NOISY
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: card_sdio_intr.c
+ *
+ * PURPOSE:
+ * Interrupt processing for the UniFi SDIO driver.
+ *
+ * We may need another signal queue of responses to UniFi to hold
+ * bulk data commands generated by read_to_host_signals().
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "driver/conversions.h"
+#include "card.h"
+#include "xbv.h"
+
+
+/*
+ * If the SDIO link is idle for this time (in milliseconds),
+ * signal UniFi to go into Deep Sleep.
+ * Valid return value of unifi_bh().
+ */
+#define UNIFI_DEFAULT_HOST_IDLE_TIMEOUT 5
+/*
+ * If the UniFi has not woken up for this time (in milliseconds),
+ * signal the bottom half to take action.
+ * Valid return value of unifi_bh().
+ */
+#define UNIFI_DEFAULT_WAKE_TIMEOUT 1000
+
+
+#define UNIFI_MAX_HOSTTAG 0x3FFFFFFF
+#define UNIFI_SOFTQUEUE_TO_HOSTTAG_SHIFT 30
+
+static int process_bh(card_t *card);
+static int handle_host_protocol(card_t *card);
+
+static int flush_fh_buffer(card_t *card);
+
+static int check_fh_sig_slots(card_t *card, unsigned int needed);
+
+static int read_to_host_signals(card_t *card);
+static int process_to_host_signals(card_t *card);
+
+static int process_bulk_data_command(card_t *card,
+ const uint8 *cmdptr,
+ int cmd, unsigned int len);
+static int process_clear_slot_command(card_t *card,
+ const uint8 *cmdptr);
+static int process_fh_cmd_queue(card_t *card);
+static int process_fh_traffic_queue(card_t *card);
+static void restart_packet_flow(card_t *card);
+
+
+#ifdef NOISY
+int dump_fh_buf = 0;
+#endif /* NOISY */
+
+static INLINE unsigned int q_data_slots_used(const q_t *q)
+{
+ unsigned int i, data_slots_used = 0;
+
+ for(i = 0; i < UNIFI_WME_NO_OF_QS; i++) {
+ data_slots_used += q_slots_used(&q[i]);
+ }
+ return data_slots_used;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_interrupt_handler
+ *
+ * This function should be called by the OS-dependent code to handle
+ * an SDIO interrupt from the UniFi.
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_sdio_interrupt_handler(card_t *card)
+{
+ int r;
+
+ /*
+ * Disable the interrupt at the host until it is acknowledged at the
+ * start of unifi_bh().
+ */
+ r = unifi_sdio_enable_interrupt(card->sdio_if, 0);
+ if (r) return;
+
+ /*
+ * Set the flag to say reason for waking was SDIO interrupt.
+ * Then ask the OS layer to run the unifi_bh to give attention to the UniFi.
+ */
+ unifi_trace(card->ospriv, UDBG5, "SDIO interrupt from UniFi.\n");
+ card->bh_reason_unifi = 1;
+ unifi_run_bh(card->ospriv);
+
+} /* sdio_interrupt_handler() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_configure_low_power_mode
+ *
+ * This function should be called by the OS-dependent when
+ * the deep sleep signaling needs to be enabled or disabled.
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ * low_power_mode Disable/Enable the deep sleep signaling
+ * periodic_wake_mode UniFi wakes host periodically.
+ *
+ * Returns:
+ * 0 on success or an error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_configure_low_power_mode(card_t *card,
+ enum unifi_low_power_mode low_power_mode,
+ enum unifi_periodic_wake_mode periodic_wake_mode)
+{
+ card->low_power_mode = low_power_mode;
+ card->periodic_wake_mode = periodic_wake_mode;
+
+ unifi_trace(card->ospriv, UDBG1,
+ "unifi_configure_low_power_mode: new mode = %s, wake_host = %s\n",
+ (low_power_mode == UNIFI_LOW_POWER_DISABLED) ? "disabled" : "enabled",
+ (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED) ? "FALSE" : "TRUE");
+ return 0;
+} /* unifi_configure_low_power_mode() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_force_low_power_mode
+ *
+ * This function should be called by the OS-dependent when
+ * UniFi needs to be set to the low power mode (e.g. on suspend)
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ *
+ * Returns:
+ * 0 on success or an error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_force_low_power_mode(card_t *card)
+{
+
+ if (card->low_power_mode == UNIFI_LOW_POWER_DISABLED) {
+ unifi_error(card->ospriv, "Attempt to set mode to TORPID when lower power mode is disabled\n");
+ return -EINVAL;
+ }
+
+ return unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
+
+} /* unifi_force_low_power_mode() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_bh
+ *
+ * This function should be called by the OS-dependent code when
+ * host and/or UniFi has requested an exchange of messages.
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ *
+ * Returns:
+ * 0 on success or an error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_bh(card_t *card, unsigned long *remaining)
+{
+ int reason_unifi, reason_host;
+ int r;
+ const enum unifi_low_power_mode low_power_mode = card->low_power_mode;
+
+ /* Disable the SDIO interrupts while doing SDIO ops */
+ r = unifi_sdio_enable_interrupt(card->sdio_if, 0);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Failed to disable SDIO interrupts. unifi_bh queues error.\n");
+ return r;
+ }
+
+
+ /*
+ * Why was the BH thread woken?
+ * If it was an SDIO interrupt, UniFi is awake and we need to process it.
+ * If it was a host process queueing data, then we need to awaken UniFi.
+ *
+ * Priority of flags is top down.
+ *
+ * ----------------------------------------------------------+
+ * \state| AWAKE | DROWSY | TORPID |
+ * flag\ | | | |
+ * ---------+--------------+----------------+----------------|
+ * | do the host | go to AWAKE and| go to AWAKE and|
+ * unifi | protocol | do the host | do the host |
+ * | | protocol | protocol |
+ * ---------+--------------+----------------+----------------|
+ * | do the host | | |
+ * host | protocol | do nothing | go to DROWSY |
+ * | | | |
+ * ---------+--------------+----------------+----------------|
+ * | | | should not |
+ * timeout | go to TORPID | error, unifi | occur |
+ * | | didn't wake up | do nothing |
+ * ----------------------------------------------------------+
+ *
+ * Note that if we end up in the AWAKE state we always do the host protocol.
+ */
+
+ do {
+ /*
+ * Copy and clear the reason flags before we process them
+ * to avoid race condition.
+ */
+ reason_unifi = card->bh_reason_unifi;
+ reason_host = card->bh_reason_host;
+ card->bh_reason_unifi = 0;
+ card->bh_reason_host = 0;
+
+ r = 0;
+ switch (card->host_state)
+ {
+ case UNIFI_HOST_STATE_AWAKE:
+ if (reason_unifi || reason_host) {
+ unifi_trace(card->ospriv, UDBG5, "UNIFI_HOST_STATE_AWAKE: Process b-h.\n");
+ (*remaining) = 0;
+ break;
+ }
+ /*
+ * if the state is AWAKE and we did not receive a request and the timeout
+ * is zero, it means that the host and UniFi are idle long enough to let
+ * UniFi go to sleep.
+ */
+ if (((*remaining) == 0) && (low_power_mode == UNIFI_LOW_POWER_ENABLED)) {
+ /* Time to let UniFi go to sleep */
+ unifi_trace(card->ospriv, UDBG5, "UNIFI_HOST_STATE_AWAKE: Set state to TORPID.\n");
+ r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
+ } else {
+ /* There is nothing to process, return immediately. */
+ r = unifi_sdio_enable_interrupt(card->sdio_if, 1);
+ if (r == -ENODEV) {
+ return r;
+ }
+ return 0;
+ }
+
+ break;
+
+ case UNIFI_HOST_STATE_DROWSY:
+ if (reason_unifi) {
+ /*
+ * If UniFi raised SDIO interrupt, then move to directly to AWAKE
+ * and do the host interface protocol.
+ */
+ unifi_trace(card->ospriv, UDBG5, "UNIFI_HOST_STATE_DROWSY: Set state to AWAKE.\n");
+ r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
+ (*remaining) = 0;
+ break;
+ }
+
+ if ((*remaining) == 0) {
+
+ unifi_error(card->ospriv, "UniFi did not wake up on time...\n");
+
+ /* Check if Function1 has gone away. */
+ r = unifi_check_io_status(card);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to read SDIO_IO_ENABLE to check for spontaneous reset\n");
+ }
+ else
+ {
+ /* See if we missed an SDIO interrupt */
+ r = CardPendingInt(card);
+ if (r == 1) {
+ unifi_error(card->ospriv, "There is an unhandled pending interrupt.\n");
+ }
+ }
+
+ /* Need to reset and reboot */
+ return -EIO;
+ } else {
+ /* There is nothing to process. */
+ r = 0;
+ }
+ break;
+
+ case UNIFI_HOST_STATE_TORPID:
+ if (reason_unifi) {
+ /*
+ * If UniFi raised SDIO interrupt, then move to directly to AWAKE
+ * and do the host interface protocol.
+ */
+ r = CardPendingInt(card);
+ if (r == 1) {
+ unifi_trace(card->ospriv, UDBG5, "UNIFI_HOST_STATE_TORPID: Set state to AWAKE.\n");
+ r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
+ (*remaining) = 0;
+ break;
+ }
+ else {
+ if (r < 0) {
+ return r;
+ }
+ reason_unifi = 0;
+ }
+ }
+
+ /* If the interrupt was spurious, a host request needs to wake up UniFi. */
+ if (reason_host && (!reason_unifi))
+ {
+ unifi_trace(card->ospriv, UDBG5, "UNIFI_HOST_STATE_TORPID: Set state to DROWSY.\n");
+ r = unifi_set_host_state(card, UNIFI_HOST_STATE_DROWSY);
+ /*
+ * Need a timeout to catch the case that UniFi dies while
+ * asleep, in which case it will never wake up.
+ */
+ if (r == 0) {
+ /* set the return value to UNIFI_DEFAULT_WAKE_TIMEOUT to capture a wake error.*/
+ (*remaining) = UNIFI_DEFAULT_WAKE_TIMEOUT;
+ }
+ } else {
+ /* There is nothing to process. */
+ r = 0;
+ }
+ break;
+
+ default:
+ unifi_error(card->ospriv, "Bad state in bh: %d\n", card->host_state);
+ break;
+ }
+
+ /* Check for an error from one of the above unifi_set_host_state() calls */
+ if (r) {
+ return r;
+ }
+
+ /* Break out and return, need to wait for the wake-up interrupt */
+ if (card->host_state == UNIFI_HOST_STATE_DROWSY) {
+ break;
+ }
+
+ /* UniFi is awake, do the host protocol */
+ if (card->host_state == UNIFI_HOST_STATE_AWAKE) {
+ r = process_bh(card);
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ } while (card->bh_reason_unifi || card->bh_reason_host);
+
+
+ /*
+ * If host is now idle, schedule a timer for the delay before we
+ * let UniFi go into deep sleep.
+ * If the timer goes off, we will move to TORPID state.
+ * If UniFi raises an interrupt in the meantime, we will cancel
+ * the timer and start a new one when we become idle.
+ */
+ if (card->host_state == UNIFI_HOST_STATE_AWAKE) {
+ if ((low_power_mode == UNIFI_LOW_POWER_ENABLED) &&
+ (q_data_slots_used(card->fh_traffic_queue) == 0))
+ {
+ if (card->ta_sampling.traffic_type != unifi_traffic_periodic) {
+ /* return the UNIFI_DEFAULT_HOST_IDLE_TIMEOUT, so we can go to sleep. */
+ unifi_trace(card->ospriv, UDBG5, "Traffic is not periodic, set timer for TORPID.\n");
+ (*remaining) = UNIFI_DEFAULT_HOST_IDLE_TIMEOUT;
+ } else {
+ unifi_trace(card->ospriv, UDBG5, "Traffic is periodic, set unifi to TORPID immediately.\n");
+ r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
+ }
+ }
+ }
+
+
+ r = unifi_sdio_enable_interrupt(card->sdio_if, 1);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Failed to enable SDIO interrupt\n");
+ return r;
+ }
+
+ unifi_trace(card->ospriv, UDBG4, "New state=%d\n", card->host_state);
+
+ return 0;
+} /* unifi_bh() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_bh
+ *
+ * Exchange messages with UniFi
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ *
+ * Returns:
+ * 0 on success or error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_bh(card_t *card)
+{
+ int r, more = 0;
+
+ /* Process the reasons (interrupt, signals) */
+ do {
+ /*
+ * Run in a while loop, to save clearing the interrupts
+ * every time around the outside loop.
+ */
+ do {
+ r = handle_host_protocol(card);
+ if (r < 0) {
+ return r;
+ }
+ more = r;
+ } while (more);
+
+ /* Acknowledge the h/w interrupt */
+ r = CardClearInt(card);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to acknowledge interrupt.\n");
+ return r;
+ }
+
+ /*
+ * UniFi may have tried to generate an interrupt during the
+ * CardClearInt() was running. So, we need to run the host
+ * protocol again, to check if there are any pending requests.
+ */
+ r = handle_host_protocol(card);
+ if (r < 0) {
+ return r;
+ }
+ more = r;
+
+ } while (more);
+
+ return 0;
+} /* process_bh() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * handle_host_protocol
+ *
+ * This function implements the Host Interface Protocol (HIP) as
+ * described in the Host Interface Protocol Specification.
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ *
+ * Returns:
+ * 0 on success or error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+handle_host_protocol(card_t *card)
+{
+ int processed_something = 0;
+ int r;
+
+#ifdef NOISY
+ printk(" ======================== \n");
+#endif /* NOISY */
+
+
+ card->generate_interrupt = 0;
+
+
+ /*
+ * (Re)fill the T-H signal buffer
+ */
+ r = read_to_host_signals(card);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Error occured reading to-host signals\n");
+ return r;
+ }
+ if (r > 0) {
+ processed_something = 1;
+ }
+
+ /*
+ * Process any to-host signals.
+ * Perform any requested CMD53 transfers here, but just queue any
+ * bulk data command responses.
+ */
+ r = process_to_host_signals(card);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Error occured processing to-host signals\n");
+ return r;
+ }
+
+ /* Now send any signals in the F-H queues */
+ /* Give precedence to the command queue */
+ r = process_fh_cmd_queue(card);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Error occured processing from-host signals\n");
+ return r;
+ }
+ if (r > 0) {
+ processed_something = 1;
+ }
+
+ r = process_fh_traffic_queue(card);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Error occured processing from-host data signals\n");
+ return r;
+ }
+ if (r > 0) {
+ processed_something = 1;
+ }
+
+ /* Flush out the batch of signals to the UniFi. */
+ r = flush_fh_buffer(card);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to copy from-host signals to UniFi\n");
+ return r;
+ }
+
+
+ /*
+ * Send the host interrupt to say the queues have been modified.
+ */
+ if (card->generate_interrupt) {
+ r = CardGenInt(card);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to notify UniFi that queues have been modified.\n");
+ return r;
+ }
+ }
+
+ /* See if we can re-enable transmission now */
+ restart_packet_flow(card);
+
+
+ /*
+ * Don't put the thread sleep if we just interacted with the chip,
+ * there might be more to do if we look again.
+ */
+ return processed_something;
+} /* handle_host_protocol() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * get_chunks_for
+ *
+ * Rounds the given signal length in bytes to a whole number
+ * of sig_frag_size.
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ * len The signal length in bytes to convert
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static INLINE unsigned int
+get_chunks_for(const card_t *card, unsigned int len)
+{
+ unsigned int mul = card->config_data.sig_frag_size;
+
+ return (len + (mul - 1)) / mul;
+} /* get_chunks_for() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_shared_count
+ *
+ * Read signal count locations, checking for an SDIO error. The
+ * signal count locations only contain a valid number if the
+ * highest bit isn't set.
+ *
+ * Arguments:
+ * card Pointer to card context structure.
+ * addr Shared-memory address to read.
+ *
+ * Returns:
+ * Value read from memory (0-127) or negative error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+read_shared_count(card_t *card, uint32 addr)
+{
+ uint8 b;
+ /* I've increased this count, because I have seen cases where
+ * there were three reads in a row with the top bit set. I'm not
+ * sure why this might have happened, but I can't see a problem
+ * with increasing this limit. It's better to take a while to
+ * recover than to fail. */
+#define SHARED_READ_RETRY_LIMIT 10
+ int r, i;
+
+ /*
+ * Get the to-host-signals-written count.
+ * The top-bit will be set if the firmware was in the process of
+ * changing the value, in which case we read again.
+ */
+ /* Limit the number of repeats so we don't freeze */
+ for (i=0; i<SHARED_READ_RETRY_LIMIT; i++) {
+ r = unifi_read8(card, addr, &b);
+ if (r) {
+ return r;
+ }
+ if (!(b & 0x80)) {
+ return (int)b;
+ }
+ }
+
+ return -EIO;
+} /* read_shared_count() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_to_host_signals
+ *
+ * Read everything pending in the UniFi TH signal buffer.
+ * Only do it if the local buffer is empty.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ *
+ * Returns:
+ * 0 if there were no signals pending,
+ * 1 if we read at least one signal
+ * -1 if an error occurred.
+ * ---------------------------------------------------------------------------
+ */
+static int
+read_to_host_signals(card_t *card)
+{
+ int count_thw, count_thr;
+ int unread_chunks, unread_bytes;
+ int r;
+
+ /* Read any pending signals or bulk data commands */
+ r = read_shared_count(card, card->sdio_ctrl_addr+4);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to read to-host sig written count\n");
+ return r;
+ }
+ count_thw = r;
+ card->to_host_signals_w = count_thw; /* diag */
+
+ count_thr = card->to_host_signals_r;
+
+ if (count_thw == count_thr) {
+ return 0;
+ }
+
+ unread_chunks =
+ (((count_thw - count_thr) + 128) % 128) - card->th_buffer.count;
+
+ if (unread_chunks == 0) {
+ return 0;
+ }
+
+ unread_bytes = card->config_data.sig_frag_size * unread_chunks;
+
+ /*
+ * Optimisation: If the length is (64*n)+m, just do the
+ * (64*n) and save the m for the next pass.
+ * This helps because a length of (64*n)+m will cause two
+ * CMD53s, one for the 64*n and one for the m.
+ */
+ /* HERE: Add this back? */
+#if 0
+ if ((unread_bytes > UNIFI_IO_BLOCK_SIZE) &&
+ (unread_bytes & (UNIFI_IO_BLOCK_SIZE-1)))
+ {
+ unifi_trace(card->ospriv, UDBG1, "Would need a double CMD53 for ths: 0x%X\n", unread_bytes);
+
+ unread_bytes &= ~(UNIFI_IO_BLOCK_SIZE - 1);
+ unread_chunks = unread_bytes / card->config_data.sig_frag_size;
+ }
+#endif
+
+ r = unifi_bulk_rw(card,
+ card->config_data.tohost_sigbuf_handle,
+ card->th_buffer.ptr,
+ unread_bytes,
+ UNIFI_SDIO_READ);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read ToHost signal\n");
+ return r;
+ }
+
+ card->th_buffer.ptr += unread_bytes;
+ card->th_buffer.count += unread_chunks;
+
+ return 1;
+
+} /* read_to_host_signals() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * update_to_host_signals_r
+ *
+ * Advance the shared-memory count of chunks read from the to-host
+ * signal buffer.
+ * Raise a UniFi internal interrupt to tell the firmware that the
+ * count has changed.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * pending Number of chunks remaining
+ *
+ * Returns:
+ * 0 on success or (SDIO) error code
+ * ---------------------------------------------------------------------------
+ */
+static int
+update_to_host_signals_r(card_t *card, int pending)
+{
+ int r;
+
+ card->to_host_signals_r =
+ (card->to_host_signals_r + (card->th_buffer.count - pending)) % 128;
+ card->th_buffer.count = pending;
+
+ /* Update the count of signals read */
+ r = unifi_write8(card, card->sdio_ctrl_addr+6, (uint8)card->to_host_signals_r);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to update to-host signals read\n");
+ return r;
+ }
+
+ r = CardGenInt(card);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to notify UniFi that we processed to-host signals.\n");
+ return r;
+ }
+
+ card->generate_interrupt = 0;
+
+ return 0;
+} /* update_to_host_signals_r() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_unpack_cmd
+ *
+ * Converts a wire-formatted command to the host bulk_data_cmd_t structure.
+ *
+ * Arguments:
+ * ptr Pointer to the command
+ * bulk_data_cmd Pointer to the host structure
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+read_unpack_cmd(const uint8 *ptr, bulk_data_cmd_t *bulk_data_cmd)
+{
+ int index = 0;
+ bulk_data_cmd->cmd_and_len = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ bulk_data_cmd->data_slot = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ bulk_data_cmd->offset = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ bulk_data_cmd->buffer_handle = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+} /* read_unpack_cmd */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_to_host_signals
+ *
+ * Read and dispatch signals from the UniFi
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ *
+ * Returns:
+ * 0 if there were no signals pending,
+ * 1 if we read at least one signal
+ * <0 if there was an error
+ *
+ * Notes:
+ * Since bulk data transfers can take a long time, if we wait until
+ * all are done before we acknowledge the signals, the UniFi runs out
+ * of buffer space. Therefore we keep a count of the bytes transferred
+ * in bulk data commands, and update the to-host-signals-read count
+ * if we've done a large transfer.
+ *
+ * All data in the f/w is stored in a little endian format, without any
+ * padding bytes. Every read from the memory has to be transformed in
+ * host (cpu specific) format, before we can process it. Therefore we
+ * use read_unpack_cmd() and read_unpack_signal() to convert the raw data
+ * contained in the card->th_buffer.buf to host structures.
+ * Important: UDI clients use wire-formatted structures, so we need to
+ * indicate all data, as we have read it from the device.
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_to_host_signals(card_t *card)
+{
+ int pending;
+ int remaining;
+ uint8 *bufptr;
+ bulk_data_param_t data_ptrs;
+ int cmd;
+ unsigned int sig_len;
+ int i;
+ unsigned int chunks_in_buf;
+ unsigned int bytes_transferred = 0;
+ int r=0;
+ uint16 signal_id;
+
+ pending = card->th_buffer.count;
+
+ /* Are there new to-host signals? */
+ unifi_trace(card->ospriv, UDBG4, "handling %d to-host chunks\n", pending);
+
+ if (!pending) {
+ return 0;
+ }
+
+ /*
+ * This is a pointer to the raw data we have read from the f/w.
+ * Can be a signal or a command. Note that we need to convert
+ * it to a host structure before we process it.
+ */
+ bufptr = card->th_buffer.buf;
+
+ while (pending > 0)
+ {
+ int f_flush_count = 0;
+
+ /*
+ * Command and length are common to signal and bulk data msgs.
+ * If command == 0 (i.e. a signal), len is number of bytes
+ * *following* the 2-byte header.
+ */
+ cmd = bufptr[1] >> 4;
+ sig_len = bufptr[0] + ((bufptr[1] & 0x0F) << 8);
+
+#ifdef NOISY
+ printk("Received UniFi msg cmd=%d, len=%d\n",
+ cmd, sig_len);
+#endif /* NOISY */
+
+ if ((sig_len == 0) &&
+ ((cmd != SDIO_CMD_CLEAR_SLOT) && (cmd != SDIO_CMD_PADDING))) {
+ unifi_error(card->ospriv, "incomplete signal or command: has size zero\n");
+ return -EIO;
+ }
+ /*
+ * Make sure the buffer contains a complete message.
+ * Signals may occupy multiple chunks, bulk-data commands occupy
+ * one chunk.
+ */
+ if (cmd == SDIO_CMD_SIGNAL) {
+ chunks_in_buf = get_chunks_for(card, sig_len + 2);
+ } else {
+ chunks_in_buf = 1;
+ }
+
+ if (chunks_in_buf > (unsigned int)pending) {
+ unifi_error(card->ospriv, "incomplete signal: need %d chunks, got %d\n",
+ chunks_in_buf, pending);
+ unifi_error(card->ospriv, " thsw=%d, thsr=%d\n",
+ card->to_host_signals_w,
+ card->to_host_signals_r);
+ return -EIO;
+ }
+
+
+ switch (cmd) {
+ case SDIO_CMD_SIGNAL:
+ /* This is a signal. Read the rest of it and then handle it. */
+
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ /* Retrieve dataRefs[i].DataLength */
+ unsigned int data_len = GET_PACKED_DATAREF_LEN(bufptr+2, i);
+
+ /*
+ * The bulk data length in the signal can not be greater than
+ * the maximun length allowed by the SDIO config structure.
+ */
+ if (data_len > card->config_data.data_slot_size) {
+ unifi_error(card->ospriv,
+ "Bulk Data length (%d) exceeds Maximum Bulk Data length (%d)\n",
+ data_len, card->config_data.data_slot_size);
+ return -EIO;
+ }
+
+ /*
+ * Len here might not be the same as the length in the
+ * bulk data slot. The slot length will always be even,
+ * but len could be odd.
+ */
+ if (data_len != 0)
+ {
+ /* Retrieve dataRefs[i].SlotNumber */
+ int slot = GET_PACKED_DATAREF_SLOT(bufptr+2, i);
+
+ if (slot >= card->config_data.num_tohost_data_slots) {
+ unifi_error(card->ospriv, "!!!bad slot number in to-host signal: %d, sig 0x%X\n",
+ slot, cmd);
+ return -EIO;
+ }
+
+ data_ptrs.d[i].os_data_ptr = card->to_host_data[slot].os_data_ptr;
+ data_ptrs.d[i].os_net_buf_ptr = card->to_host_data[slot].os_net_buf_ptr;
+ data_ptrs.d[i].net_buf_length = card->to_host_data[slot].net_buf_length;
+ data_ptrs.d[i].data_length = data_len;
+
+ }
+ else
+ {
+ unifi_init_bulk_data(&data_ptrs.d[i]);
+ }
+ }
+
+ /*
+ * Log the signal to the UDI, before call unifi_receive_event() as
+ * it can modify the bulk data.
+ */
+ if (card->udi_hook) {
+ (*card->udi_hook)(card->ospriv, bufptr+2, sig_len,
+ &data_ptrs, UDI_LOG_TO_HOST);
+ }
+
+ signal_id = GET_SIGNAL_ID(bufptr+2);
+ if (signal_id == CSR_MA_UNITDATA_CONFIRM_ID) {
+ uint32 priority_q, host_tag;
+
+ /*
+ * We have stored the queue number the packet was originaly
+ * sent from in the host tag field.
+ * Do not forget to restore the original host tag.
+ */
+ host_tag = GET_PACKED_MA_UNIDATA_STATUS_INDICATION_HOSTTAG(bufptr+2);
+ priority_q = host_tag >> UNIFI_SOFTQUEUE_TO_HOSTTAG_SHIFT;
+ if (priority_q < UNIFI_WME_NO_OF_QS) {
+ card->fh_pending_unitdata_req[priority_q] --;
+ } else {
+ unifi_warning(card->ospriv,
+ "MA_STATUS_INDICATION: queue (%d) must be less than %d.\n",
+ priority_q, UNIFI_WME_NO_OF_QS);
+ }
+ SET_PACKED_MA_UNIDATA_STATUS_INDICATION_HOSTTAG(bufptr+2, host_tag & UNIFI_MAX_HOSTTAG);
+ unifi_trace(card->ospriv, UDBG4, "MA_STATUS_INDICATION: %d pending packets in queue %d.\n",
+ card->fh_pending_unitdata_req[priority_q], priority_q);
+ }
+
+ /* Pass event to OS layer */
+ unifi_receive_event(card->ospriv, bufptr+2, sig_len, &data_ptrs);
+
+ /* Initialise the to_host data, so it can be re-used. */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ /* The slot is only valid if the length is non-zero. */
+ if (GET_PACKED_DATAREF_LEN(bufptr+2, i) != 0) {
+ int slot = GET_PACKED_DATAREF_SLOT(bufptr+2, i);
+ if (slot < card->config_data.num_tohost_data_slots) {
+ unifi_init_bulk_data(&card->to_host_data[slot]);
+ }
+ }
+ }
+
+ /*
+ * If we have previously transferred a lot of data, ack
+ * the signals read so far, so f/w can reclaim the buffer
+ * memory sooner.
+ */
+ if (bytes_transferred >= TO_HOST_FLUSH_THRESHOLD) {
+ f_flush_count = 1;
+ }
+ break;
+
+
+ case SDIO_CMD_CLEAR_SLOT:
+ /* This is a clear slot command. */
+ if (sig_len != 0) {
+ unifi_error(card->ospriv, "process_to_host_signals: clear slot, bad data len: 0x%X at offset %d\n",
+ sig_len, bufptr - card->th_buffer.buf);
+ return -EIO;
+ }
+
+ r = process_clear_slot_command(card, bufptr);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to process clear slot\n");
+ return r;
+ }
+ break;
+
+ case SDIO_CMD_TO_HOST_TRANSFER:
+ case SDIO_CMD_FROM_HOST_TRANSFER:
+ case SDIO_CMD_FROM_HOST_AND_CLEAR:
+ case SDIO_CMD_OVERLAY_TRANSFER:
+ /* This is a bulk data command. */
+ if (sig_len & 1) {
+ unifi_error(card->ospriv, "process_to_host_signals: bulk data, bad data len: 0x%X at offset %d\n",
+ sig_len, bufptr - card->th_buffer.buf);
+ return -EIO;
+ }
+
+ r = process_bulk_data_command(card, bufptr, cmd, sig_len);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to process bulk cmd\n");
+ return r;
+ }
+ /* Count the bytes transferred */
+ bytes_transferred += sig_len;
+
+ if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR) {
+ f_flush_count = 1;
+ }
+ break;
+
+ case SDIO_CMD_PADDING:
+ break;
+
+ default:
+ unifi_error(card->ospriv, "Unrecognised to-host command: %d\n", cmd);
+ break;
+ }
+
+ bufptr += chunks_in_buf * card->config_data.sig_frag_size;
+ pending -= chunks_in_buf;
+
+ /*
+ * Write out the host signal count when a significant
+ * number of bytes of bulk data have been transferred or
+ * when we have performed a CopyFromHostAndClear.
+ */
+ if (f_flush_count) {
+ r = update_to_host_signals_r(card, pending);
+ if (r) {
+ return r;
+ }
+ bytes_transferred = 0;
+ }
+
+ }
+
+ if (pending) {
+ unifi_warning(card->ospriv, "proc_th_sigs: %d unprocessed\n", pending);
+ }
+
+ /* If we processed any signals, write the updated count to UniFi */
+ if (card->th_buffer.count != pending)
+ {
+ r = update_to_host_signals_r(card, pending);
+ if (r) {
+ return r;
+ }
+ }
+
+ /*
+ * Reset the buffer pointer, copying down any un-processed signals.
+ * This can happen if we enable the optimisation in read_to_host_signals()
+ * that limits the length to whole blocks.
+ */
+ remaining = card->th_buffer.ptr - bufptr;
+ if (remaining < 0) {
+ unifi_error(card->ospriv, "Processing TH signals overran the buffer\n");
+ return -EIO;
+ }
+ if (remaining > 0) {
+ /* Use a safe copy because source and destination may overlap */
+ unsigned char *d = card->th_buffer.buf;
+ unsigned char *s = bufptr;
+ int n = remaining;
+ while (n--) {
+ *d++ = *s++;
+ }
+ }
+ card->th_buffer.ptr = card->th_buffer.buf + remaining;
+
+
+ /* If we reach here then we processed something */
+ return 1;
+} /* process_to_host_signals() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_overlay_cmd
+ *
+ * Process a f/w overlay request from the UniFi. This function finds
+ * the sectionof the FWOV from the XBV and returns it to the caller.
+ * The caller must then send it to UniFi.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * bdslot A Bulk Data slot to be filled with the correct section of
+ * the fimware overlay.
+ * fw_offset The offset into the firmware overlay section requested by
+ * the firmware
+ * req_len The length of firmware data reqquested by the firmware.
+ *
+ * Returns:
+ * 0 on success, -1 on error
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_overlay_cmd(card_t *card,
+ bulk_data_desc_t *bdslot, uint32 fw_offset, unsigned int req_len)
+{
+ void *dlpriv;
+ unsigned int file_read_len;
+ int r;
+ const struct FWOV *fwov = &card->fwov;
+
+ func_enter();
+
+ /* Start reading the f/w file */
+ dlpriv = unifi_fw_read_start(card->ospriv, UNIFI_FW_STA);
+ if (dlpriv == NULL) {
+ unifi_error(card->ospriv, "f/w file read failed\n");
+ func_exit();
+ return -EINVAL;
+ }
+
+ /*
+ * The request length might be rounded-up to the UNIFI_IO_SDIO_SIZE size
+ * which means that we my don't have enough data in the file to give to
+ * the f/w. In this case we need to pad the buffer.
+ */
+ if (fw_offset + req_len > fwov->dl_size) {
+ if (req_len % card->sdio_io_block_size == 0) {
+ /* Firmware file not big enough, the buffer will be padded. */
+ if (fw_offset >= fwov->dl_size) {
+ unifi_error(card->ospriv, "offset (%u) exceeds section size (%u)\n",
+ fw_offset, fwov->dl_size);
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+ func_exit();
+ return -EINVAL;
+ }
+ file_read_len = fwov->dl_size - fw_offset;
+ } else {
+ unifi_error(card->ospriv, "Request size (%u) is not an I/O block size (%u) multiple\n",
+ req_len, card->sdio_io_block_size);
+ unifi_error(card->ospriv, "and FWOV section not big enough\n");
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+ func_exit();
+ return -EINVAL;
+ }
+ } else {
+ /* We have enough data in the f/w file. */
+ file_read_len = req_len;
+ }
+
+ /* Allocate a buffer with the request length. */
+ r = unifi_net_data_malloc(card->ospriv, bdslot, req_len);
+ if (r != 0) {
+ unifi_error(card->ospriv, "Failed to allocate f/w overlay buffer\n");
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+ func_exit();
+ return -EIO;
+ }
+
+ /* Read as much data as we can from the f/w file. */
+ r = unifi_fw_read(card->ospriv, dlpriv, fwov->dl_offset + fw_offset,
+ (void*)bdslot->os_data_ptr, file_read_len);
+ if (r < 0 || (unsigned int)r != file_read_len) {
+ unifi_error(card->ospriv, "Failed (fw_offset=%u, len=%u, ret:%d)\n",
+ fw_offset, file_read_len, r);
+ unifi_net_data_free(card->ospriv, bdslot);
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+ func_exit();
+ return -EINVAL;
+ }
+
+ unifi_fw_read_stop(card->ospriv, dlpriv);
+
+ func_exit();
+ return 0;
+}
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_clear_slot_command
+ *
+ * Process a clear slot command fom the UniFi.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * bdcmd Pointer to bulk-data command msg from UniFi
+ *
+ * Returns:
+ * 0 on success, -1 on error
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_clear_slot_command(card_t *card, const uint8 *cmdptr)
+{
+ uint16 data_slot;
+ int slot;
+
+ data_slot = UNPACK16(cmdptr, SIZEOF_UINT16);
+
+ unifi_trace(card->ospriv, UDBG4, "Processing clear slot cmd, slot=0x%X\n",
+ data_slot);
+
+ slot = data_slot & 0x7FFF;
+
+#ifdef NOISY
+ printk("CMD clear data slot 0x%04x\n", data_slot);
+#endif /* NOISY */
+
+ if (data_slot & SLOT_DIR_TO_HOST) {
+ if (slot >= card->config_data.num_tohost_data_slots) {
+ unifi_error(card->ospriv,
+ "Invalid to-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
+ slot);
+ return -EIO;
+ }
+ /* clear to-host data slot */
+ unifi_warning(card->ospriv, "Unexpected clear to-host data slot cmd: 0x%04x\n",
+ data_slot);
+ } else {
+ if (slot >= card->config_data.num_fromhost_data_slots) {
+ unifi_error(card->ospriv,
+ "Invalid from-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
+ slot);
+ return -EIO;
+ }
+
+ /* Set length field in from_host_data array to 0 */
+ CardClearFromHostDataSlot(card, slot);
+ }
+
+ return 0;
+} /* process_clear_slot_command() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_bulk_data_command
+ *
+ * Process a bulk data request from the UniFi.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * bdcmd Pointer to bulk-data command msg from UniFi
+ * cmd, len Decoded values of command and length from the msg header
+ * Cmd will only be one of:
+ * SDIO_CMD_TO_HOST_TRANSFER
+ * SDIO_CMD_FROM_HOST_TRANSFER
+ * SDIO_CMD_FROM_HOST_AND_CLEAR
+ * SDIO_CMD_OVERLAY_TRANSFER
+ *
+ * Returns:
+ * 0 on success, -1 on error
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_bulk_data_command(card_t *card, const uint8 *cmdptr,
+ int cmd, unsigned int len)
+{
+ bulk_data_desc_t *bdslot;
+ bulk_data_cmd_t bdcmd;
+ int offset;
+ int slot;
+ int dir;
+ int r;
+ bulk_data_desc_t overlay_bdslot;
+
+ read_unpack_cmd(cmdptr, &bdcmd);
+
+ unifi_trace(card->ospriv, UDBG4, "Processing bulk data cmd %d %s, len=%d, slot=0x%X\n",
+ cmd, lookup_bulkcmd_name(cmd), len, bdcmd.data_slot);
+
+ /*
+ * Round up the transfer length if required.
+ * This is useful to force all transfers to be a multiple of the SDIO block
+ * size, so the SDIO driver won't try to use a byte-mode CMD53. These are
+ * broken on some hardware platforms.
+ */
+#ifdef UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE
+ len = (len + card->sdio_io_block_size - 1) & ~(card->sdio_io_block_size - 1);
+ unifi_trace(card->ospriv, UDBG4, "Rounded bulk data length up to %d\n", len);
+#endif /* UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE */
+
+ slot = bdcmd.data_slot & 0x7FFF;
+
+ if (cmd == SDIO_CMD_OVERLAY_TRANSFER) {
+ uint32 fw_offset;
+ /* In the case of SDIO_CMD_OVERLAY_TRANSFER, the bulk data command fields are different. */
+ fw_offset = UNPACK32(cmdptr, SIZEOF_UINT16);
+
+ r = process_overlay_cmd(card, &overlay_bdslot, fw_offset, len);
+ if (r) {
+ return r;
+ }
+
+ bdslot = &overlay_bdslot;
+ offset = 0;
+ } else {
+ if (bdcmd.data_slot & SLOT_DIR_TO_HOST) {
+ /* Request is for to-host bulk data */
+
+ /* Check sanity of slot number */
+ if (slot >= card->config_data.num_tohost_data_slots) {
+ unifi_error(card->ospriv,
+ "Invalid to-host data slot in SDIO bulk xfr req: %d\n",
+ slot);
+ return -EIO;
+ }
+
+ /* Allocate memory for card->to_host_data[slot] bulk data here. */
+ r = unifi_net_data_malloc(card->ospriv, &card->to_host_data[slot], len);
+ if (r != 0) {
+ unifi_error(card->ospriv, "Failed to allocate t-h bulk data\n");
+ return -EIO;
+ }
+
+ bdslot = &card->to_host_data[slot];
+ } else {
+ /* Request is for from-host bulk data */
+
+ if (slot >= card->config_data.num_fromhost_data_slots) {
+ unifi_error(card->ospriv,
+ "Invalid from-host data slot in SDIO bulk xfr req: %d\n",
+ slot);
+ return -EIO;
+ }
+ bdslot = &card->from_host_data[slot];
+ }
+ offset = bdcmd.offset;
+ }
+ /* Do the transfer */
+ dir = (cmd == SDIO_CMD_TO_HOST_TRANSFER) ?
+ UNIFI_SDIO_READ : UNIFI_SDIO_WRITE;
+
+ unifi_trace(card->ospriv, UDBG4, "Bulk %s len=%d, handle %d -- slot=%d %p+0x%X\n",
+ lookup_bulkcmd_name(cmd),
+ len,
+ bdcmd.buffer_handle,
+ slot, bdslot->os_data_ptr, offset);
+#ifdef NOISY
+ printk("Bulk %s len=%d, handle %d -- slot=%d %p+0x%X\n",
+ lookup_bulkcmd_name(cmd),
+ len,
+ bdcmd.buffer_handle,
+ slot, bdslot->os_data_ptr, offset);
+#endif /* NOISY */
+
+ r = unifi_bulk_rw(card,
+ bdcmd.buffer_handle,
+ (void*)(bdslot->os_data_ptr + offset),
+ len,
+ dir);
+
+ if (cmd == SDIO_CMD_OVERLAY_TRANSFER) {
+ unifi_net_data_free(card->ospriv, &overlay_bdslot);
+ return r;
+ }
+ if (r == -ENODEV) return r;
+ if (r) {
+#if 1
+ unifi_error(card->ospriv, "Bulk data transfer failed:"
+ "Bulk %s len=%d, handle %d -- slot=%d %p+0x%X\n",
+ lookup_bulkcmd_name(cmd),
+ len,
+ bdcmd.buffer_handle,
+ slot, bdslot->os_data_ptr, offset);
+#endif
+ return r;
+ }
+
+ bdslot->data_length = len;
+
+ if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR) {
+ if (slot >= card->config_data.num_fromhost_data_slots) {
+ unifi_error(card->ospriv,
+ "Invalid from-host data slot in SDIO_CMD_FROM_HOST_AND_CLEAR: %d\n",
+ slot);
+ return -EIO;
+ }
+
+ /* Set length field in from_host_data array to 0 */
+ CardClearFromHostDataSlot(card, slot);
+ }
+
+ return 0;
+} /* process_bulk_data_command() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * check_fh_sig_slots
+ *
+ * Check whether there are <n> free signal slots available on UniFi.
+ * This takes into account the signals already batched since the
+ * from_host_signal counts were last read.
+ * If the from_host_signal counts indicate not enough space, we read
+ * the latest count from UniFi to see if some more have been freed.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+check_fh_sig_slots(card_t *card, unsigned int needed)
+{
+ unsigned int count_fhw, count_fhr;
+ unsigned int occupied_fh, space_fh, slots_fh;
+
+ count_fhw = card->from_host_signals_w;
+ count_fhr = card->from_host_signals_r;
+ slots_fh = card->config_data.num_fromhost_sig_frags;
+
+ /* Only read the space in from-host queue if necessary */
+ occupied_fh = (count_fhw - count_fhr) % 128;
+
+ if (slots_fh < occupied_fh) {
+ space_fh = 0;
+ } else {
+ space_fh = slots_fh - occupied_fh;
+ }
+
+ if ((occupied_fh != 0) && (space_fh < needed))
+ {
+ int r;
+ r = read_shared_count(card, card->sdio_ctrl_addr+2);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to read from-host sig read count\n");
+ return r;
+ }
+ count_fhr = r;
+ card->from_host_signals_r = count_fhr; /* diag */
+
+ occupied_fh = (count_fhw - count_fhr) % 128;
+ space_fh = slots_fh - occupied_fh;
+ }
+
+ return (int)space_fh;
+} /* check_fh_sig_slots() */
+
+
+
+static INLINE unsigned int
+free_chunks_in_fh_buffer(card_t *card)
+{
+ return get_chunks_for(card,
+ (card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr);
+}
+
+
+static INLINE unsigned int
+round_up_needed_chunks(card_t *card, unsigned int needed_chunks)
+{
+
+#ifdef UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE
+ unsigned int chunks_per_block;
+ unsigned int chunks_in_last_block;
+
+ /*
+ * If we are padding the From-Host signals to the SDIO block size,
+ * we need to round up the needed_chunks to the SDIO block size.
+ */
+
+ /* chunks in a block size */
+ chunks_per_block = card->sdio_io_block_size / card->config_data.sig_frag_size;
+ /* chunks out of the block size */
+ chunks_in_last_block = needed_chunks % chunks_per_block;
+
+ /* Increase the needed_chunks to be a multiple of chunks_per_block */
+ if (chunks_in_last_block != 0) {
+ return needed_chunks + (chunks_per_block - chunks_in_last_block);
+ } else {
+ return needed_chunks;
+ }
+
+#else
+
+ return needed_chunks;
+#endif
+}
+
+
+static INLINE unsigned int
+round_up_space_chunks(card_t *card, unsigned int space_chunks)
+{
+#ifdef UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE
+ unsigned int chunks_per_block;
+
+ /* chunks in a block size */
+ chunks_per_block = card->sdio_io_block_size / card->config_data.sig_frag_size;
+
+ if ((space_chunks / chunks_per_block) == 0) {
+ return 0;
+ }
+
+ return ((space_chunks / chunks_per_block) * chunks_per_block);
+#else
+ return space_chunks;
+#endif
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_fh_cmd_queue
+ *
+ * Take one signal off the from-host queue and copy it to the UniFi.
+ * Does nothing if the UniFi has no slots free.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ *
+ * Returns:
+ * 0 if there is nothing on the queue to process
+ * 1 if a signal was successfully processed
+ * -1 if an error occurred.
+ *
+ * Notes:
+ * The from-host queue contains signal requests from the network driver
+ * and any UDI clients interspersed. UDI clients' requests have been stored
+ * in the from-host queue using the wire-format structures, as they arrive.
+ * All other requests are stored in the from-host queue using the host
+ * (cpu specific) structures. We use the is_packed member of the card_signal_t
+ * structure that describes the queue to make the distiction.
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_fh_cmd_queue(card_t *card)
+{
+ q_t *sigq = &card->fh_command_queue;
+
+ int processed = 0;
+ unsigned int pending_sigs;
+ unsigned int pending_chunks;
+ unsigned int needed_chunks;
+ int space_chunks;
+ unsigned int q_index;
+
+ /* Get the number of pending signals. */
+ pending_sigs = q_slots_used(sigq);
+ unifi_trace(card->ospriv, UDBG5, "proc_fh: %d pending\n", pending_sigs);
+ if (pending_sigs == 0)
+ {
+ /* Nothing to do */
+ return 0;
+ }
+
+ /* Work out how many chunks we have waiting to send */
+ for (pending_chunks = 0, q_index = q_next_r_slot(sigq);
+ q_index != q_next_w_slot(sigq);
+ q_index = q_wrap(sigq, q_index + 1))
+ {
+ card_signal_t *csptr = q_slot_data(sigq, q_index);
+
+ /*
+ * Note that get_chunks_for() needs the size of the packed
+ * (wire-formatted) structure
+ */
+ pending_chunks += get_chunks_for(card, csptr->signal_length + 2);
+ }
+
+ /*
+ * Check whether UniFi has space for all the buffered bulk-data
+ * commands and signals as well.
+ */
+ needed_chunks = pending_chunks + card->fh_buffer.count;
+
+ /* Round up to the block size if necessary */
+ needed_chunks = round_up_needed_chunks(card, needed_chunks);
+
+ space_chunks = check_fh_sig_slots(card, needed_chunks);
+ if (space_chunks < 0) {
+ /* Error */
+ unifi_error(card->ospriv, "Failed to read fh sig count\n");
+ return space_chunks;
+ }
+
+#ifdef NOISY
+ printk("proc_fh: %d chunks free, need %d\n", space_chunks, needed_chunks);
+#endif /* NOISY */
+
+
+ /*
+ * Coalesce as many from-host signals as possible
+ * into a single block and write using a single CMD53
+ */
+ if (needed_chunks > (unsigned int)space_chunks) {
+
+ /* Round up to the block size if necessary */
+ space_chunks = round_up_space_chunks(card, space_chunks);
+
+ /*
+ * If the f/w has less free chunks than those already pending
+ * return immediately.
+ */
+ if ((unsigned int)space_chunks <= card->fh_buffer.count) {
+ /*
+ * No room in UniFi for any signals after the buffered bulk
+ * data commands have been sent.
+ */
+ unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
+ card->fh_buffer.count, space_chunks);
+ card->generate_interrupt = 1;
+ return 0;
+ }
+ pending_chunks = space_chunks - card->fh_buffer.count;
+ }
+
+ while (pending_sigs-- && pending_chunks > 0)
+ {
+ card_signal_t *csptr;
+ int i;
+ unsigned int sig_chunks, total_length;
+ unsigned int num_data_refs;
+ bulk_data_param_t bulkdata;
+ unsigned char *packed_sigptr;
+ unsigned int signal_length = 0;
+
+ /* Retrieve the entry at the head of the queue */
+ q_index = q_next_r_slot(sigq);
+
+ /* Get a pointer to the containing card_signal_t struct */
+ csptr = q_slot_data(sigq, q_index);
+
+ /* Get the new length of the packed signal */
+ signal_length = csptr->signal_length;
+
+ if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE)) {
+ unifi_error(card->ospriv, "process_fh_queue: Bad len: %d\n", signal_length);
+ return -EIO;
+ }
+
+ /* Need space for 2-byte SDIO protocol header + signal */
+ sig_chunks = get_chunks_for(card, signal_length + 2);
+ if (free_chunks_in_fh_buffer(card) < sig_chunks) {
+ /* No more room */
+ unifi_notice(card->ospriv, "proc_fh_cmd_q: no room in fh buffer for %s, deferring\n",
+ lookup_signal_name(GET_SIGNAL_ID(csptr->sigbuf)));
+ break;
+ }
+
+ /* Count the used data slots. */
+ num_data_refs = 0;
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ if (csptr->bulkdata[i].data_length != 0) {
+ num_data_refs++;
+ }
+ }
+
+ /* Check that there are enough empty data slots. */
+ if ((num_data_refs != 0) &&
+ (CardGetFreeFromHostDataSlots(card) < num_data_refs))
+ {
+ unifi_notice(card->ospriv, "proc_fh_cmd_q: no fh data slots for %s, deferring\n",
+ lookup_signal_name(GET_SIGNAL_ID(csptr->sigbuf)));
+ break;
+ }
+
+ packed_sigptr = csptr->sigbuf;
+
+ /*
+ * Claim data slots for the bulk data. We already know slots
+ * will be available. This should be the only place where we
+ * poke values into SlotNumber and DataLength.
+ */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i)
+ {
+ unsigned int datalen = csptr->bulkdata[i].data_length;
+
+ bulkdata.d[i].data_length = datalen;
+ if (datalen == 0) {
+ /* Zero-out the DATAREF in the signal */
+ SET_PACKED_DATAREF_SLOT(packed_sigptr, i, 0);
+ SET_PACKED_DATAREF_LEN(packed_sigptr, i, 0);
+
+ unifi_init_bulk_data(&bulkdata.d[i]);
+ }
+ else
+ {
+ /* Claim and set up a from-host data slot. */
+ int slotnum = CardWriteBulkData(card, &csptr->bulkdata[i]);
+
+ if (slotnum < 0) {
+ unifi_error(card->ospriv, "Failed to get from host data slot\n");
+ return -EIO;
+ }
+ if ((slotnum > 65535) || (datalen > 65535)) {
+ unifi_error(card->ospriv, "Bad data slot (%u:%u)\n", slotnum, datalen);
+ return -EIO;
+ }
+
+ /* Fill in the slot number in the SIGNAL structure. */
+ SET_PACKED_DATAREF_SLOT(packed_sigptr, i, slotnum);
+ SET_PACKED_DATAREF_LEN(packed_sigptr, i, datalen);
+ bulkdata.d[i].os_data_ptr = card->from_host_data[slotnum].os_data_ptr;
+ bulkdata.d[i].data_length = card->from_host_data[slotnum].data_length;
+
+ }
+ }
+
+ unifi_trace(card->ospriv, UDBG2, "Sending signal 0x%X %s\n",
+ GET_SIGNAL_ID(packed_sigptr),
+ lookup_signal_name(GET_SIGNAL_ID(packed_sigptr)));
+#ifdef NOISY
+ printk("Sending signal 0x%X %s\n",
+ GET_SIGNAL_ID(packed_sigptr),
+ lookup_signal_name(GET_SIGNAL_ID(packed_sigptr)));
+#endif /* NOISY */
+
+
+ /* Append packed signal to F-H buffer */
+ total_length = sig_chunks * card->config_data.sig_frag_size;
+
+ card->fh_buffer.ptr[0] = signal_length & 0xff;
+ card->fh_buffer.ptr[1] =
+ ((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4);
+
+ memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
+ memset(card->fh_buffer.ptr + 2 + signal_length, 0,
+ total_length - (2 + signal_length));
+
+#ifdef NOISY
+ printk("proc_fh: fh_buffer %d bytes \n", signal_length+2);
+ dump(card->fh_buffer.ptr, signal_length+2);
+ unifi_trace(card->ospriv, UDBG1, " \n");
+#endif /* NOISY */
+
+ card->fh_buffer.ptr += total_length;
+ card->fh_buffer.count += sig_chunks;
+
+#ifdef NOISY
+ printk("Added %d to fh buf, len now %d, count %d\n",
+ signal_length,
+ card->fh_buffer.ptr - card->fh_buffer.buf,
+ card->fh_buffer.count);
+#endif /* NOISY */
+
+ processed++;
+ pending_chunks -= sig_chunks;
+
+ /* Log the signal to the UDI. */
+ /* UDI will get the packed structure */
+ /* Can not log the unpacked signal, unless we reconstruct it! */
+ if (card->udi_hook) {
+ (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
+ &bulkdata, UDI_LOG_FROM_HOST);
+ }
+
+ /* Remove entry from q */
+ csptr->signal_length = 0;
+ q_inc_r(sigq);
+ }
+
+ return processed;
+} /* process_fh_cmd_queue() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_fh_traffic_queue
+ *
+ * Take signals off the from-host queue and copy them to the UniFi.
+ * Does nothing if the UniFi has no slots free.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * sigq Pointer to the traffic queue
+ *
+ * Returns:
+ * 0 if there is nothing on the queue to process
+ * 1 if a signal was successfully processed
+ * -1 if an error occurred.
+ *
+ * Notes:
+ * The from-host queue contains signal requests from the network driver
+ * and any UDI clients interspersed.
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_fh_traffic_queue(card_t *card)
+{
+ q_t *sigq = card->fh_traffic_queue;
+
+ int processed = 0, n, restrict_queues = 0, q_no;
+ unsigned int pending_sigs = 0;
+ unsigned int pending_chunks = 0;
+ unsigned int needed_chunks;
+ int space_chunks;
+ unsigned int q_index;
+
+ /* calculate how many signals are in queues and how many chunks are needed. */
+ for (n = UNIFI_WME_NO_OF_QS - 1; n >= 0; n--) {
+ /* Get the number of pending signals. */
+ pending_sigs += q_slots_used(&sigq[n]);
+ unifi_trace(card->ospriv, UDBG5, "proc_fh%d: %d pending\n", n, pending_sigs);
+
+ /* Work out how many chunks we have waiting to send */
+ for (q_index = q_next_r_slot(&sigq[n]);
+ q_index != q_next_w_slot(&sigq[n]);
+ q_index = q_wrap(&sigq[n], q_index + 1))
+ {
+ card_signal_t *csptr = q_slot_data(&sigq[n], q_index);
+
+ /*
+ * Note that get_chunks_for() needs the size of the packed
+ * (wire-formatted) structure
+ */
+ pending_chunks += get_chunks_for(card, csptr->signal_length + 2);
+ }
+
+ }
+
+ /* If there are no pending signals, just return */
+ if (pending_sigs == 0)
+ {
+ /* Nothing to do */
+ return 0;
+ }
+
+ /*
+ * Check whether UniFi has space for all the buffered bulk-data
+ * commands and signals as well.
+ */
+ needed_chunks = pending_chunks + card->fh_buffer.count;
+
+ /* Round up to the block size if necessary */
+ needed_chunks = round_up_needed_chunks(card, needed_chunks);
+
+ space_chunks = check_fh_sig_slots(card, needed_chunks);
+ if (space_chunks < 0) {
+ /* Error */
+ unifi_error(card->ospriv, "Failed to read fh sig count\n");
+ return space_chunks;
+ }
+
+#ifdef NOISY
+ printk("process_fh_traffic_queue: %d chunks free, need %d\n", space_chunks, needed_chunks);
+ read_fhsr(card); /* debugging only */
+#endif /* NOISY */
+
+ /* Coalesce as many from-host signals as possible
+ into a single block and write using a single CMD53 */
+ if (needed_chunks > (unsigned int)space_chunks) {
+
+ /* Round up to the block size if necessary */
+ space_chunks = round_up_space_chunks(card, space_chunks);
+
+ if ((unsigned int)space_chunks <= card->fh_buffer.count) {
+ /*
+ * No room in UniFi for any signals after the buffered bulk
+ * data commands have been sent.
+ */
+ unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
+ card->fh_buffer.count, space_chunks);
+ card->generate_interrupt = 1;
+ return 0;
+ }
+
+ pending_chunks = space_chunks - card->fh_buffer.count;
+ /* We do not have enough available chunks, we are going to restrict signals per queue */
+ restrict_queues = 1;
+ }
+
+ /*
+ * pending_sigs will be exhausted if there are is no restriction to the pending
+ * signals per queue. pending_chunks may be exhausted if there is a restriction.
+ * q_no check will be exhausted if there is a restriction and our round-robin
+ * algorith fails to fill all chunks.
+ */
+ q_no = UNIFI_WME_NO_OF_QS - 1;
+ while ((pending_sigs > 0) && (pending_chunks > 0) && (q_no >= 0))
+ {
+ card_signal_t *csptr;
+ unsigned int sig_chunks, total_length;
+ unsigned int num_data_refs;
+ bulk_data_param_t bulkdata;
+ unsigned char *packed_sigptr;
+ unsigned int signal_length = 0;
+ int i;
+ uint32 host_tag;
+
+ /* if this queue is empty go to next one. */
+ if (q_slots_used(&sigq[q_no]) == 0) {
+ q_no--;
+ continue;
+ }
+
+ /* If the queue is full do not apply restrictions.*/
+ if (q_slots_free(&sigq[q_no]) >= RESUME_XMIT_THRESHOLD) {
+ /* In case we do not have space for all signals in all queues.. */
+ if (restrict_queues || (q_slots_used(&sigq[q_no]) != pending_sigs)) {
+ /* .. we restrict pending signals for each queue. */
+ if (card->fh_pending_unitdata_req[q_no] >= MAX_PENDING_SIGNALS_PER_Q) {
+ /* Process next queue */
+ q_no--;
+ continue;
+ }
+ }
+ }
+
+ /* Retrieve the entry at the head of the queue */
+ q_index = q_next_r_slot(&sigq[q_no]);
+
+ /* Get a pointer to the containing card_signal_t struct */
+ csptr = q_slot_data(&sigq[q_no], q_index);
+
+ /* Get the new length of the packed signal */
+ signal_length = csptr->signal_length;
+
+ if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE)) {
+ unifi_error(card->ospriv, "process_fh_traffic_queue: Bad len: %d\n", signal_length);
+ return -EIO;
+ }
+
+ /* Need space for 2-byte SDIO protocol header + signal */
+ sig_chunks = get_chunks_for(card, signal_length + 2);
+ if (free_chunks_in_fh_buffer(card) < sig_chunks) {
+ /* No more room */
+ unifi_notice(card->ospriv, "process_fh_traffic_queue: no more chunks.\n");
+ break;
+ }
+
+ /* Count the used data slots.
+ * Note that the traffic queue has only one valid bulk data buffer.
+ */
+ num_data_refs = 0;
+ if (csptr->bulkdata[0].data_length != 0) {
+ num_data_refs++;
+ }
+
+ /*
+ * Check that there are enough empty data slots.
+ * We reserve 2 bulk data slots exclusively for the command queue.
+ * The original check is:
+ * num_data_refs > CardGetFreeFromHostDataSlots(card) - 2
+ * but CardGetFreeFromHostDataSlots might return a number
+ * less than 2 which means that the result may wrap around.
+ */
+ if ((num_data_refs != 0) &&
+ (CardGetFreeFromHostDataSlots(card) < (num_data_refs + 2))) {
+ break;
+ }
+
+ packed_sigptr = csptr->sigbuf;
+ /*
+ * Claim data slots for the bulk data. We already know slots
+ * will be available. This should be the only place where we
+ * poke values into SlotNumber and DataLength.
+ * Note that the traffic queue has only one valid bulk data buffer.
+ */
+ {
+ unsigned int datalen = csptr->bulkdata[0].data_length;
+
+ /*
+ * The bulkdata structure is used by the udi_hook callback
+ * to log the signal to the logging registered clients.
+ * The compiler may not initialise the structure to zero.
+ * Since this is a data signal and we use only the first bulk
+ * data ref, we set the length of the rest bulk data refs to zero.
+ */
+ for (i = 1; i < UNIFI_MAX_DATA_REFERENCES; i++)
+ {
+ bulkdata.d[i].data_length = 0;
+ }
+
+ bulkdata.d[0].data_length = datalen;
+ if (datalen == 0) {
+ /* Zero-out the DATAREF in the signal */
+ SET_PACKED_DATAREF_SLOT(packed_sigptr, 0, 0);
+ SET_PACKED_DATAREF_LEN(packed_sigptr, 0, 0);
+
+ unifi_init_bulk_data(&bulkdata.d[i]);
+ }
+ else
+ {
+ /* Claim and set up a from-host data slot. */
+ int slotnum = CardWriteBulkData(card, &csptr->bulkdata[0]);
+
+ if (slotnum < 0) {
+ unifi_error(card->ospriv, "Failed to get from host data slot\n");
+ return -EIO;
+ }
+ if ((slotnum > 65535) || (datalen > 65535)) {
+ unifi_error(card->ospriv, "Bad data slot (%u:%u)\n", slotnum, datalen);
+ return -EIO;
+ }
+
+ /* Fill in the slot number in the SIGNAL structure. */
+ SET_PACKED_DATAREF_SLOT(packed_sigptr, 0, slotnum);
+ SET_PACKED_DATAREF_LEN(packed_sigptr, 0, datalen);
+ bulkdata.d[0].os_data_ptr = card->from_host_data[slotnum].os_data_ptr;
+ bulkdata.d[0].data_length = card->from_host_data[slotnum].data_length;
+ bulkdata.d[0].os_net_buf_ptr = card->from_host_data[slotnum].os_net_buf_ptr;
+ bulkdata.d[0].net_buf_length = card->from_host_data[slotnum].net_buf_length;
+
+ }
+ }
+
+ unifi_trace(card->ospriv, UDBG3, "Sending signal 0x%X %s\n",
+ GET_SIGNAL_ID(packed_sigptr),
+ lookup_signal_name(GET_SIGNAL_ID(packed_sigptr)));
+#ifdef NOISY
+ printk("Sending signal 0x%X %s\n",
+ GET_SIGNAL_ID(packed_sigptr),
+ lookup_signal_name(GET_SIGNAL_ID(packed_sigptr)));
+#endif /* NOISY */
+
+ /* Append packed signal to F-H buffer */
+ total_length = sig_chunks * card->config_data.sig_frag_size;
+
+ card->fh_buffer.ptr[0] = signal_length & 0xff;
+ card->fh_buffer.ptr[1] =
+ ((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4);
+
+ /*
+ * Use the host tag field to store the queue number.
+ * It is used to update the fh_pending_unitdata_req when the
+ * MA_UNITDATA.cfm is received.
+ */
+ if(GET_SIGNAL_ID(packed_sigptr) == CSR_MA_UNITDATA_REQUEST_ID) {
+ host_tag = GET_PACKED_MA_UNIDATA_REQUEST_HOSTTAG(packed_sigptr);
+ SET_PACKED_MA_UNIDATA_REQUEST_HOSTTAG(packed_sigptr,
+ (host_tag | (q_no << UNIFI_SOFTQUEUE_TO_HOSTTAG_SHIFT)));
+ }
+
+ memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
+ memset(card->fh_buffer.ptr + 2 + signal_length, 0,
+ total_length - (2 + signal_length));
+
+#ifdef NOISY
+ printk("proc_fh: fh_buffer %d bytes \n", signal_length+2);
+ dump(card->fh_buffer.ptr, signal_length+2);
+ unifi_trace(card->ospriv, UDBG1, " \n");
+#endif /* NOISY */
+
+ card->fh_buffer.ptr += total_length;
+ card->fh_buffer.count += sig_chunks;
+
+#ifdef NOISY
+ printk("Added %d to fh buf, len now %d, count %d\n",
+ signal_length,
+ card->fh_buffer.ptr - card->fh_buffer.buf,
+ card->fh_buffer.count);
+#endif /* NOISY */
+
+ processed++;
+ pending_sigs--;
+ pending_chunks -= sig_chunks;
+
+ /* Log the signal to the UDI. */
+ /* UDI will get the packed structure */
+ /* Can not log the unpacked signal, unless we reconstruct it! */
+ if (card->udi_hook) {
+ (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
+ &bulkdata, UDI_LOG_FROM_HOST);
+ }
+
+ /* Remove entry from q */
+ csptr->signal_length = 0;
+ /* Note that the traffic queue has only one valid bulk data buffer. */
+ csptr->bulkdata[0].data_length = 0;
+
+ q_inc_r(&sigq[q_no]);
+
+ /* Update counter of pending signals, per queue. */
+ card->fh_pending_unitdata_req[q_no]++;
+ unifi_trace(card->ospriv, UDBG3, "process_fh_traffic_queue: %d pending requests in queue %d\n",
+ card->fh_pending_unitdata_req[q_no], q_no);
+ }
+
+ return processed;
+} /* process_fh_traffic_queue() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * flush_fh_buffer
+ *
+ * Write out the cache from-hosts signals to the UniFi.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ *
+ * Returns:
+ * 0 if there is nothing in the buffer to process
+ * -1 if an SDIO error occurred.
+ * ---------------------------------------------------------------------------
+ */
+static int
+flush_fh_buffer(card_t *card)
+{
+ int r;
+ unsigned int len;
+#ifdef UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE
+ unsigned int sig_units;
+ unsigned int data_round;
+ unsigned int chunks_in_last_block;
+ unsigned int padding_chunks;
+ unsigned int i;
+#endif
+
+ len = card->fh_buffer.ptr - card->fh_buffer.buf;
+
+#ifdef NOISY
+ printk("fh_buffer is at %p, ptr= %p\n",
+ card->fh_buffer.buf, card->fh_buffer.ptr);
+#endif /* NOISY */
+
+ if (len == 0) {
+ return 0;
+ }
+
+#ifdef NOISY
+ if (dump_fh_buf) {
+ dump(card->fh_buffer.buf, len);
+ dump_fh_buf = 0;
+ }
+#endif /* NOISY */
+
+#ifdef UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE
+ /* Both of these are powers of 2 */
+ sig_units = card->config_data.sig_frag_size;
+ data_round = card->sdio_io_block_size;
+
+ if (data_round > sig_units) {
+ chunks_in_last_block = (len % data_round) / sig_units;
+
+ if (chunks_in_last_block != 0) {
+ padding_chunks = (data_round / sig_units) - chunks_in_last_block;
+
+ memset(card->fh_buffer.ptr, 0, padding_chunks * sig_units);
+ for (i = 0; i < padding_chunks; i++) {
+ card->fh_buffer.ptr[1] = SDIO_CMD_PADDING << 4;
+ card->fh_buffer.ptr += sig_units;
+ }
+
+ card->fh_buffer.count += padding_chunks;
+ len += padding_chunks * sig_units;
+ }
+ }
+#endif
+
+ r = unifi_bulk_rw(card,
+ card->config_data.fromhost_sigbuf_handle,
+ card->fh_buffer.buf,
+ len, UNIFI_SDIO_WRITE);
+ if (r == -ENODEV) return r;
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to write fh signals: %u bytes, error %d\n", len, r);
+ return r;
+ }
+
+ /* Update from-host-signals-written signal count */
+ card->from_host_signals_w =
+ (card->from_host_signals_w + card->fh_buffer.count) % 128u;
+ r = unifi_write8(card, card->sdio_ctrl_addr+0, (uint8)card->from_host_signals_w);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Failed to write fh signal count %u with error %d\n",
+ card->from_host_signals_w, r);
+ return r;
+ }
+ card->generate_interrupt = 1;
+
+ /* Reset the fh buffer pointer */
+ card->fh_buffer.ptr = card->fh_buffer.buf;
+ card->fh_buffer.count = 0;
+
+#ifdef NOISY
+ printk("END flush: fh len %d, count %d\n",
+ card->fh_buffer.ptr - card->fh_buffer.buf,
+ card->fh_buffer.count);
+#endif /* NOISY */
+
+ return 0;
+} /* flush_fh_buffer() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * restart_packet_flow
+ *
+ * This function is called before the bottom-half thread sleeps.
+ * It checks whether both data and signal resources are available and
+ * then calls the OS-layer function to re-enable packet transmission.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+restart_packet_flow(card_t *card)
+{
+ /*
+ * We only look at the fh_traffic_queue, because that is where packets from
+ * the network stack are placed.
+ */
+ if (card->paused &&
+ (q_slots_free(&card->fh_traffic_queue[0]) >= RESUME_XMIT_THRESHOLD) &&
+ (q_slots_free(&card->fh_traffic_queue[1]) >= RESUME_XMIT_THRESHOLD) &&
+ (q_slots_free(&card->fh_traffic_queue[2]) >= RESUME_XMIT_THRESHOLD) &&
+ (q_slots_free(&card->fh_traffic_queue[3]) >= RESUME_XMIT_THRESHOLD)
+ )
+ {
+ /*
+ * Clear the paused flag *before* calling
+ * unifi_restart_xmit(). The calling sequence down through
+ * unifi_restart_xmit() could possibly call all the way to
+ * unifi_send_signal() and unifi_pause_xmit(). When that
+ * happens, paused will have been set again, so we don't then
+ * want to clear it.
+ */
+ card->paused = 0;
+ unifi_restart_xmit(card->ospriv);
+ }
+} /* restart_packet_flow() */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_mem.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_mem.c
new file mode 100644
index 0000000..a5abf72
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/card_sdio_mem.c
@@ -0,0 +1,1301 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: card_sdio_mem.c
+ *
+ * PURPOSE: Implementation of the Card API for SDIO.
+ *
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "card.h"
+
+#define SDIO_RETRIES 3
+
+
+#define retryable_sdio_error(_r) (((_r) == -EIO) || ((_r) == -ETIMEDOUT))
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * retrying_readb
+ * retrying_writeb
+ *
+ * These functions provide the first level of retry for SDIO operations.
+ * If an SDIO command fails for reason of a response timeout or CRC
+ * error, it is retried immediately. If three attempts fail we report a
+ * failure.
+ * If the command failed for any other reason, the failure is reported
+ * immediately.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * funcnum The SDIO function to access.
+ * Function 0 is the Card Configuration Register space,
+ * function 1/2 is the UniFi register space.
+ * addr Address to access
+ * pdata Pointer in which to return the value read.
+ * data Value to write.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+static INLINE int
+retrying_readb(card_t *card, int funcnum,
+ unsigned long addr, unsigned char *pdata)
+{
+ void *sdio = card->sdio_if;
+ int r = 0;
+ int retries;
+
+ retries = 0;
+ while (retries++ < SDIO_RETRIES) {
+ r = unifi_sdio_readb(sdio, funcnum, addr, pdata);
+ if (r == -ENODEV) {
+ return r;
+ }
+ /*
+ * Try again for retryable (CRC or TIMEOUT) errors,
+ * break on success or fatal error
+ */
+ if (!retryable_sdio_error(r)) {
+ break;
+ }
+ unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
+ }
+
+ if ((r == 0) && (retries > 1)) {
+ unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
+ }
+
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
+ addr, retries - 1);
+ /* Report any SDIO error as a general i/o error */
+ r = -EIO;
+ }
+
+ return r;
+} /* retrying_readb() */
+
+
+static INLINE int
+retrying_writeb(card_t *card, int funcnum,
+ unsigned long addr, unsigned char data)
+{
+ void *sdio = card->sdio_if;
+ int r = 0;
+ int retries;
+
+ retries = 0;
+ while (retries++ < SDIO_RETRIES) {
+ r = unifi_sdio_writeb(sdio, funcnum, addr, data);
+ if (r == -ENODEV) {
+ return r;
+ }
+ /*
+ * Try again for retryable (CRC or TIMEOUT) errors,
+ * break on success or fatal error
+ */
+ if (!retryable_sdio_error(r)) {
+ break;
+ }
+ unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
+ data, funcnum, addr);
+ }
+
+ if ((r == 0) && (retries > 1)) {
+ unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
+ }
+
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
+ addr, retries - 1);
+ /* Report any SDIO error as a general i/o error */
+ r = -EIO;
+ }
+
+ return r;
+} /* retrying_writeb() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * sdio_read_f0
+ *
+ * Reads a byte value from the CCCR (func 0) area of UniFi.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Address to read from
+ * pdata Pointer in which to store the read value.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+sdio_read_f0(card_t *card, unsigned long addr, uint8 *pdata)
+{
+ return retrying_readb(card, 0, addr, pdata);
+} /* sdio_read_f0() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * sdio_write_f0
+ *
+ * Writes a byte value to the CCCR (func 0) area of UniFi.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Address to read from
+ * data Data value to write.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+sdio_write_f0(card_t *card, unsigned long addr, uint8 data)
+{
+ return retrying_writeb(card, 0, addr, data);
+} /* sdio_write_f0() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read_direct8
+ *
+ * Read a 8-bit value from the UniFi SDIO interface.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Address to read from
+ * pdata Pointer in which to return data.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_read_direct8(card_t *card, unsigned long addr, uint8 *pdata)
+{
+ int r;
+ unsigned char b;
+
+ r = retrying_readb(card, card->function, addr, &b);
+ if (r) {
+ return r;
+ }
+
+ *pdata = b;
+
+ return 0;
+} /* unifi_read_direct8() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_write_direct8
+ *
+ * Write a byte value to the UniFi SDIO interface.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Address to write to
+ * data Value to write.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * The even address *must* be written second. This is because writes to
+ * odd bytes are cached and not committed to memory until the preceding
+ * even address is written.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_write_direct8(card_t *card, unsigned long addr, uint8 data)
+{
+ if (addr & 1) {
+ unifi_warning(card->ospriv, "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
+ addr);
+ }
+ return retrying_writeb(card, card->function, addr, data);
+} /* unifi_write_direct8() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read_direct16
+ *
+ * Read a 16-bit value from the UniFi SDIO interface.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Address to read from
+ * pdata Pointer in which to return data.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * The even address *must* be read first. This is because reads from
+ * odd bytes are cached and read from memory when the preceding
+ * even address is read.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_read_direct16(card_t *card, unsigned long addr, uint16 *pdata)
+{
+ int r;
+ unsigned char b0, b1;
+
+ r = retrying_readb(card, card->function, addr, &b0);
+ if (r) {
+ return r;
+ }
+
+ r = retrying_readb(card, card->function, addr+1, &b1);
+ if (r) {
+ return r;
+ }
+
+ *pdata = ((uint16)b1 << 8) | b0;
+
+ return 0;
+} /* unifi_read_direct16() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_write_direct16
+ *
+ * Write a 16-bit value to the UniFi SDIO interface.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Address to write to
+ * data Value to write.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * The even address *must* be written second. This is because writes to
+ * odd bytes are cached and not committed to memory until the preceding
+ * even address is written.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_write_direct16(card_t *card, unsigned long addr, uint16 data)
+{
+ int r;
+ unsigned char b0, b1;
+
+ b1 = (data >> 8) & 0xFF;
+ r = retrying_writeb(card, card->function, addr+1, b1);
+ if (r) {
+ return r;
+ }
+
+ b0 = data & 0xFF;
+ r = retrying_writeb(card, card->function, addr, b0);
+ if (r) {
+ return r;
+ }
+
+ return 0;
+} /* unifi_write_direct16() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read_direct32
+ *
+ * Read a 32-bit value from the UniFi SDIO interface.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Address to read from
+ * pdata Pointer in which to return data.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_read_direct32(card_t *card, unsigned long addr, uint32 *pdata)
+{
+ int r;
+ unsigned char b0, b1, b2, b3;
+
+ r = retrying_readb(card, card->function, addr, &b0);
+ if (r) {
+ return r;
+ }
+
+ r = retrying_readb(card, card->function, addr+1, &b1);
+ if (r) {
+ return r;
+ }
+
+ r = retrying_readb(card, card->function, addr+2, &b2);
+ if (r) {
+ return r;
+ }
+
+ r = retrying_readb(card, card->function, addr+3, &b3);
+ if (r) {
+ return r;
+ }
+
+ *pdata = ((uint32)b3 << 24) | ((uint32)b2 << 16) | ((uint32)b1 << 8) | b0;
+
+ return 0;
+} /* unifi_read_direct32() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read_directn_match
+ *
+ * Read multiple 8-bit values from the UniFi SDIO interface,
+ * stopping when either we have read 'len' bytes or we have read
+ * a octet equal to 'match'. If 'match' is not a valid octet
+ * then this function is the same as 'unifi_read_directn'.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Start address to read from.
+ * pdata Pointer to which to write data.
+ * len Maximum umber of bytes to read
+ * match The value to stop reading at.
+ *
+ * Returns:
+ * number of octets read on success, negative error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * The even address *must* be read first. This is because reads from
+ * odd bytes are cached and read from memory when the preceding
+ * even address is read.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_read_directn_match(card_t *card, unsigned long addr, void *pdata, int len, int m)
+{
+ int r, i;
+ unsigned char b;
+ unsigned char *cptr;
+
+ cptr = (unsigned char *)pdata;
+ for (i=0; i<len; i++) {
+ r = retrying_readb(card, card->function, addr, &b);
+ if (r) {
+ return r;
+ }
+
+ *cptr++ = b;
+ addr++;
+
+ if ((m >= 0) && ((int)b == m)) {
+ break;
+ }
+ }
+
+ return cptr - (unsigned char *)pdata;
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read_directn
+ *
+ * Read multiple 8-bit values from the UniFi SDIO interface.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Start address to read from.
+ * pdata Pointer to which to write data.
+ * len Number of bytes to read
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * The even address *must* be read first. This is because reads from
+ * odd bytes are cached and read from memory when the preceding
+ * even address is read.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_read_directn(card_t *card, unsigned long addr, void *pdata, int len)
+{
+ int r;
+ r = unifi_read_directn_match(card, addr, pdata, len, -1);
+ return (r < 0) ? r : 0;
+} /* unifi_read_directn() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_write_directn
+ *
+ * Write multiple 8-bit values to the UniFi SDIO interface.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * addr Start address to write to.
+ * pdata Source data pointer.
+ * len Number of bytes to write, must be even.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * The UniFi has a peculiar 16-bit bus architecture. Writes are only
+ * committed to memory when an even address is accessed. Writes to
+ * odd addresses are cached and only committed if the next write is
+ * to the preceding address.
+ * This means we must write data as pairs of bytes in reverse order.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_write_directn(card_t *card, unsigned long addr, void *pdata, int len)
+{
+ int r;
+ unsigned char b0, b1;
+ unsigned char *cptr;
+
+ cptr = (unsigned char *)pdata;
+ while (len) {
+ b0 = *cptr++;
+ b1 = *cptr++;
+
+ r = retrying_writeb(card, card->function, addr+1, b1);
+ if (r) {
+ return r;
+ }
+
+ r = retrying_writeb(card, card->function, addr, b0);
+ if (r) {
+ return r;
+ }
+
+ addr += 2;
+ len -= 2;
+ }
+
+ return 0;
+} /* unifi_write_directn() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_dmem_page
+ * set_pmem_page
+ *
+ * Set up the page register for the shared data memory window or program
+ * memory window.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * dmem_addr UniFi shared-data-memory address to access.
+ * pmem_addr UniFi program memory address to access. This includes
+ * External FLASH memory at 0x000000
+ * Processor program memory at 0x200000
+ * External SRAM at memory 0x400000
+ *
+ * Returns:
+ * Returns a SDIO address (24-bit) for use in a unifi_read_direct or
+ * unifi_write_direct call, or a negative error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_dmem_page(card_t *card, unsigned long dmem_addr)
+{
+ uint16 page, addr;
+ uint32 len;
+ int r;
+
+ if (!ChipHelper_DecodeWindow(card->helper,
+ CHIP_HELPER_WINDOW_3,
+ CHIP_HELPER_WT_SHARED,
+ dmem_addr / 2,
+ &page, &addr, &len)) {
+ unifi_error(card->ospriv, "Failed to decode SHARED_DMEM_PAGE %08lx\n", dmem_addr);
+ return -EINVAL;
+ }
+
+ if (page != card->dmem_page) {
+ unifi_trace(card->ospriv, UDBG6, "setting dmem page=0x%X, addr=0x%lX\n", page, addr);
+
+ /* change page register */
+ r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, page);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
+ return r;
+ }
+
+ card->dmem_page = page;
+ }
+
+ return ((unsigned int)addr * 2) + (dmem_addr & 1);
+} /* set_dmem_page() */
+
+
+
+static int
+set_pmem_page(card_t *card, unsigned long pmem_addr,
+ enum chip_helper_window_type mem_type)
+{
+ uint16 page, addr;
+ uint32 len;
+ int r;
+
+ if (!ChipHelper_DecodeWindow(card->helper,
+ CHIP_HELPER_WINDOW_2,
+ mem_type,
+ pmem_addr / 2,
+ &page, &addr, &len)) {
+ unifi_error(card->ospriv, "Failed to decode PROG MEM PAGE %08lx %d\n", pmem_addr, mem_type);
+ return -EINVAL;
+ }
+
+ if (page != card->pmem_page) {
+ unifi_trace(card->ospriv, UDBG6, "setting pmem page=0x%X, addr=0x%lX\n", page, addr);
+
+ /* change page register */
+ r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, page);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write PROG MEM PAGE\n");
+ return r;
+ }
+
+ card->pmem_page = page;
+ }
+
+ return ((unsigned int)addr * 2) + (pmem_addr & 1);
+} /* set_pmem_page() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_page
+ *
+ * Sets up the appropriate page register to access the given address.
+ * Returns the sdio address at which the unifi address can be accessed.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * generic_addr UniFi internal address to access, in Generic Pointer
+ * format, i.e. top byte is space indicator.
+ *
+ * Returns:
+ * Returns a SDIO address (24-bit) for use in a unifi_read_direct or
+ * unifi_write_direct call, or a negative error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_page(card_t *card, unsigned long generic_addr)
+{
+ int space;
+ unsigned long addr;
+ int sdio_addr;
+ int r;
+
+ space = UNIFI_GP_SPACE(generic_addr);
+ addr = UNIFI_GP_OFFSET(generic_addr);
+ switch (space)
+ {
+ case UNIFI_SH_DMEM:
+ /* Shared Data Memory is accessed via the Shared Data Memory window */
+ sdio_addr = set_dmem_page(card, addr);
+ break;
+
+ case UNIFI_EXT_FLASH:
+ if (!ChipHelper_HasFlash(card->helper)) {
+ unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+ /* External FLASH is accessed via the Program Memory window */
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_FLASH);
+ break;
+
+ case UNIFI_EXT_SRAM:
+ if (!ChipHelper_HasExtSram(card->helper)) {
+ unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+ /* External SRAM is accessed via the Program Memory window */
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_EXT_SRAM);
+ break;
+
+ case UNIFI_REGISTERS:
+ /* Registers are accessed directly */
+ sdio_addr = addr;
+ break;
+
+ case UNIFI_PHY_DMEM:
+ r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
+ if (r)
+ return r;
+ sdio_addr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
+ break;
+
+ case UNIFI_MAC_DMEM:
+ r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
+ if (r)
+ return r;
+ sdio_addr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
+ break;
+
+ case UNIFI_BT_DMEM:
+ if (!ChipHelper_HasBt(card->helper)) {
+ unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+ r = unifi_set_proc_select(card, UNIFI_PROC_BT);
+ if (r)
+ return r;
+ sdio_addr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
+ break;
+
+ case UNIFI_PHY_PMEM:
+ r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
+ if (r)
+ return r;
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM);
+ break;
+
+ case UNIFI_MAC_PMEM:
+ r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
+ if (r)
+ return r;
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM);
+ break;
+
+ case UNIFI_BT_PMEM:
+ if (!ChipHelper_HasBt(card->helper)) {
+ unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+ r = unifi_set_proc_select(card, UNIFI_PROC_BT);
+ if (r)
+ return r;
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM);
+ break;
+
+ case UNIFI_PHY_ROM:
+ if (!ChipHelper_HasRom(card->helper)) {
+ unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+ r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
+ if (r)
+ return r;
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM);
+ break;
+
+ case UNIFI_MAC_ROM:
+ if (!ChipHelper_HasRom(card->helper)) {
+ unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+ r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
+ if (r)
+ return r;
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM);
+ break;
+
+ case UNIFI_BT_ROM:
+ if (!ChipHelper_HasRom(card->helper) || !ChipHelper_HasBt(card->helper)) {
+ unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+ r = unifi_set_proc_select(card, UNIFI_PROC_BT);
+ if (r)
+ return r;
+ sdio_addr = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM);
+ break;
+
+ default:
+ unifi_error(card->ospriv, "Bad address space in generic pointer 0x%08lX\n",
+ generic_addr);
+ return -EINVAL;
+ }
+
+ return sdio_addr;
+
+} /* set_page() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_set_proc_select
+ *
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_set_proc_select(card_t *card, int select)
+{
+ int r;
+
+ /* Verify the the select value is allowed. */
+ switch (select)
+ {
+ case UNIFI_PROC_MAC:
+ case UNIFI_PROC_PHY:
+ case UNIFI_PROC_BOTH:
+ break;
+
+
+ default:
+ return -EINVAL;
+ }
+
+ if (card->proc_select != select) {
+
+ r = unifi_write_direct8(card, ChipHelper_DBG_HOST_PROC_SELECT(card->helper) * 2, select);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write to Proc Select register\n");
+ return r;
+ }
+
+ card->proc_select = select;
+ }
+
+ return 0;
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read8
+ *
+ * Performs a byte read of the given address in shared data memory.
+ * Set up the shared data memory page register as required.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * pdata Pointer to a byte variable for the value read.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * -EINVAL a bad generic pointer was specified
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_read8(card_t *card, unsigned long unifi_addr, uint8 *pdata)
+{
+ int sdio_addr;
+
+ sdio_addr = set_page(card, unifi_addr);
+ if (sdio_addr < 0) {
+ return sdio_addr;
+ }
+
+ return unifi_read_direct8(card, sdio_addr, pdata);
+} /* unifi_read8() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_write8
+ *
+ * Performs a byte write of the given address in shared data memory.
+ * Set up the shared data memory page register as required.
+ *
+ * Arguments:
+ * card Pointer to card context struct.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * data Value to write.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * -EINVAL a bad generic pointer was specified
+ *
+ * Notes:
+ * Beware using unifi_write8() because byte writes are not safe on UniFi.
+ * Writes to odd bytes are cached, writes to even bytes perform a 16-bit
+ * write with the previously cached odd byte.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_write8(card_t *card, unsigned long unifi_addr, uint8 data)
+{
+ int sdio_addr;
+
+ sdio_addr = set_page(card, unifi_addr);
+ if (sdio_addr < 0) {
+ return sdio_addr;
+ }
+
+ return unifi_write_direct8(card, sdio_addr, data);
+} /* unifi_write8() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read16
+ *
+ * Performs a 16-bit read of the given address in shared data memory.
+ * Set up the shared data memory page register as required.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * pdata Pointer to a 16-bit int variable for the value read.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * -EINVAL a bad generic pointer was specified
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_read16(card_t *card, unsigned long unifi_addr, uint16 *pdata)
+{
+ int sdio_addr;
+
+ sdio_addr = set_page(card, unifi_addr);
+ if (sdio_addr < 0) {
+ return sdio_addr;
+ }
+
+ return unifi_read_direct16(card, sdio_addr, pdata);
+} /* unifi_read16() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_write16
+ *
+ * Performs a 16-bit write of the given address in shared data memory.
+ * Set up the shared data memory page register as required.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * pdata Pointer to a byte variable for the value write.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * -EINVAL a bad generic pointer was specified
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_write16(card_t *card, unsigned long unifi_addr, uint16 data)
+{
+ int sdio_addr;
+
+ sdio_addr = set_page(card, unifi_addr);
+ if (sdio_addr < 0) {
+ return sdio_addr;
+ }
+
+ return unifi_write_direct16(card, sdio_addr, data);
+} /* unifi_write16() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read32
+ *
+ * Performs a 32-bit read of the given address in shared data memory.
+ * Set up the shared data memory page register as required.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * pdata Pointer to a int variable for the value read.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * -EINVAL a bad generic pointer was specified
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_read32(card_t *card, unsigned long unifi_addr, uint32 *pdata)
+{
+ int sdio_addr;
+
+ sdio_addr = set_page(card, unifi_addr);
+ if (sdio_addr < 0) {
+ return sdio_addr;
+ }
+
+ return unifi_read_direct32(card, sdio_addr, pdata);
+} /* unifi_read32() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_readn
+ * unifi_readnz
+ *
+ * Read multiple 8-bit values from the UniFi SDIO interface.
+ * This function interprets the address as a GenericPointer as
+ * defined in the UniFi Host Interface Protocol Specification.
+ * The readnz version of this function will stop when it reads a
+ * zero octet.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * pdata Pointer to which to write data.
+ * len Number of bytes to read
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * -EINVAL a bad generic pointer was specified
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_readn_match(card_t *card, unsigned long unifi_addr, void *pdata, int len, int match)
+{
+ int sdio_addr, r;
+
+ sdio_addr = set_page(card, unifi_addr);
+ if (sdio_addr < 0) {
+ return sdio_addr;
+ }
+
+ r = unifi_read_directn_match(card, sdio_addr, pdata, len, match);
+ return (r < 0) ? r : 0;
+} /* unifi_readn_match() */
+
+int
+unifi_readn(card_t *card, unsigned long unifi_addr, void *pdata, int len)
+{
+ return unifi_readn_match(card, unifi_addr, pdata, len, -1);
+} /* unifi_readn() */
+
+int
+unifi_readnz(card_t *card, unsigned long unifi_addr, void *pdata, int len)
+{
+ return unifi_readn_match(card, unifi_addr, pdata, len, 0);
+} /* unifi_readnz() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_writen
+ *
+ * Write multiple 8-bit values to the UniFi SDIO interface using CMD52
+ * This function interprets the address as a GenericPointer as
+ * defined in the UniFi Host Interface Protocol Specification.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * pdata Pointer to which to write data.
+ * len Number of bytes to write
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ * -EINVAL an odd length or length too big.
+ * -ETIMEDOUT timed out waiting for rewind.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_writen(card_t *card, unsigned long unifi_addr, void *pdata, int len)
+{
+ int sdio_addr;
+
+ sdio_addr = set_page(card, unifi_addr);
+ if (sdio_addr < 0) {
+ return sdio_addr;
+ }
+
+ return unifi_write_directn(card, sdio_addr, pdata, len);
+} /* unifi_writen() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_bulk_rw
+ *
+ * Transfer bulk data to or from the UniFi SDIO interface.
+ * This function is used to read or write signals and bulk data.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * handle Value to put in the Register Address field of the CMD53 req.
+ * data Pointer to data to write.
+ * direction One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * This function uses SDIO CMD53, which is the block transfer mode.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_bulk_rw(card_t *card, unsigned long handle, void *pdata,
+ unsigned int len, int direction)
+{
+#define CMD53_RETRIES 3
+/* The spec gives us no hint as to what these should be, I've seen
+ * 50,10 time out, so I've upped them. I can see no real problem with
+ * this, if a better mechanism is required then we should trigger off
+ * the interrupt generated by UniFi when the rewind handle is reset. */
+#define REWIND_RETRIES 250 /* 5, 50 */
+#define REWIND_DELAY 20 /* 10, 10 */
+ int r = 0;
+ int retries = CMD53_RETRIES;
+ int stat_retries;
+ uint8 stat;
+#ifdef MAKE_FAKE_CMD53_ERRORS
+ static int fake_error;
+#endif
+ int dump_read;
+
+ dump_read = 0;
+ if (((unsigned long)pdata) & 1) {
+ unifi_notice(card->ospriv, "CD53 request on a unaligned buffer (addr: 0x%X) dir %s-Host\n",
+ pdata, (direction == UNIFI_SDIO_READ) ? "To" : "From");
+ if (direction == UNIFI_SDIO_WRITE) {
+ dump(pdata, len);
+ } else {
+ dump_read = 1;
+ }
+ }
+
+ /* Defensive check */
+ if ((len & 1) || (len > 0xffff)) {
+ unifi_error(card->ospriv, "Impossible CMD53 length requested: %d\n", len);
+ return -EINVAL;
+ }
+
+ while (1)
+ {
+ r = unifi_sdio_block_rw(card->sdio_if, card->function, handle,
+ (unsigned char *)pdata, len, direction);
+ if (r == -ENODEV) {
+ return r;
+ }
+#ifdef MAKE_FAKE_CMD53_ERRORS
+ if (++fake_error > 100) {
+ fake_error = 90;
+ unifi_warning(card->ospriv, "Faking a CMD53 error,\n");
+ if (r == 0) {
+ r = -EIO;
+ }
+ }
+#endif
+ if (r == 0) {
+ /* success */
+ if (dump_read) {
+ dump(pdata, len);
+ }
+ break;
+ }
+
+ /*
+ * At this point the SDIO driver should have written the I/O Abort
+ * register to notify UniFi that the command has failed.
+ * UniFi-1 and UniFi-2 use the same register to store the
+ * Deep Sleep State. This means we have to restore the Deep Sleep
+ * State (AWAKE in any case since we can not perform a CD53 in any other
+ * state) by rewritting the I/O Abort register to its' previous value.
+ */
+ unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
+
+ if (!retryable_sdio_error(r)) {
+ unifi_error(card->ospriv, "Fatal error in a CMD53 transfer\n");
+ break;
+ }
+
+ /*
+ * These happen from time to time, life sucks, try again
+ */
+ unifi_notice(card->ospriv, "Error in a CMD53 transfer, retrying (h:%d,l:%u)...\n",
+ (int)handle & 0xff, len);
+
+ if (--retries == 0) {
+ break;
+ }
+
+ /* The transfer failed, rewind and try again */
+ r = unifi_write8(card, card->sdio_ctrl_addr+8, (uint8)(handle & 0xff));
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ /*
+ * If we can't even do CMD52 (register read/write) then
+ * stop here.
+ */
+ unifi_error(card->ospriv, "Failed to write REWIND cmd\n");
+ return r;
+ }
+
+ /* Signal the UniFi to look for the rewind request. */
+ r = CardGenInt(card);
+ if (r) {
+ return r;
+ }
+
+ /* Wait for UniFi to acknowledge the rewind */
+ stat_retries = REWIND_RETRIES;
+ while (1) {
+ r = unifi_read8(card, card->sdio_ctrl_addr+8, &stat);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read REWIND status\n");
+ return -EIO;
+ }
+ if (stat == 0) {
+ break;
+ }
+ if (--stat_retries == 0) {
+ unifi_error(card->ospriv, "Timeout waiting for REWIND ready\n");
+ return -ETIMEDOUT;
+ }
+ unifi_delay_us(card->ospriv, REWIND_DELAY);
+ }
+
+ }
+
+ if (r) {
+ unifi_error(card->ospriv, "Block %s failed after %d retries\n",
+ (direction == UNIFI_SDIO_READ) ? "read" : "write",
+ CMD53_RETRIES - retries);
+ /* Report any SDIO error as a general i/o error */
+ return -EIO;
+ }
+
+ /* Collect some stats */
+ if (direction == UNIFI_SDIO_READ) {
+ card->sdio_bytes_read += len;
+ } else {
+ card->sdio_bytes_written += len;
+ }
+
+ return 0;
+} /* unifi_bulk_rw() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_bulk_rw
+ *
+ * Transfer bulk data to or from the UniFi SDIO interface.
+ * This function is used to read or write signals and bulk data.
+ *
+ * Arguments:
+ * card Pointer to card structure.
+ * handle Value to put in the Register Address field of
+ * the CMD53 req.
+ * data Pointer to data to write.
+ * direction One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error:
+ * -ENODEV card was ejected
+ * -EIO an SDIO error occurred
+ *
+ * Notes:
+ * This function uses SDIO CMD53, which is the block transfer mode.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_bulk_rw_noretry(card_t *card, unsigned long handle, void *pdata,
+ unsigned int len, int direction)
+{
+ int r;
+
+ r = unifi_sdio_block_rw(card->sdio_if, card->function, handle,
+ (unsigned char *)pdata, len, direction);
+ if (r == -ENODEV) {
+ return r;
+ }
+ if (r) {
+ unifi_error(card->ospriv, "Block %s failed\n",
+ (direction == UNIFI_SDIO_READ) ? "read" : "write");
+ /* Report any SDIO error as a general i/o error */
+ r = -EIO;
+ }
+
+ return r;
+} /* unifi_bulk_rw() */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.c
new file mode 100644
index 0000000..92c64ad
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.c
@@ -0,0 +1,715 @@
+/*
+FILE
+ chiphelper.c
+*/
+
+#include "chiphelper_private.h"
+
+#ifndef nelem
+#define nelem(a) (sizeof(a) / sizeof(a[0]))
+#endif
+
+#define counted(foo) { nelem(foo), foo }
+#define null_counted() { 0, NULL }
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/* The init values are a set of register writes that we must
+ perform when we first connect to the chip to get it working.
+ They swicth on the correct clocks and possibly set the host
+ interface as a wkaeup source. They should not be used if
+ proper HIP opperation is required, but are useful before we
+ do a code download. */
+static const struct chip_helper_init_values init_vals_v1[] = {
+ { 0xFDBB, 0xFFFF },
+ { 0xFDB6, 0x03FF },
+ { 0xFDB1, 0x01E3 },
+ { 0xFDB3, 0x0FFF },
+ { 0xFEE3, 0x08F0 },
+ { 0xFEE7, 0x3C3F },
+ { 0xFEE6, 0x0050 },
+ { 0xFDBA, 0x0000 }
+};
+
+static const struct chip_helper_init_values init_vals_v2[] = {
+ { 0xFDB6, 0x0FFF },
+ { 0xF023, 0x3F3F },
+ { 0xFDB1, 0x01E3 },
+ { 0xFDB3, 0x0FFF },
+ { 0xF003, 0x08F0 },
+ { 0xF007, 0x3C3F },
+ { 0xF006, 0x0050 }
+};
+
+
+static const struct chip_helper_init_values init_vals_v22_v23[] = {
+ { 0xF81C, 0x00FF },
+ /*{ 0x????, 0x???? }, */
+ { 0xF80C, 0x1FFF },
+ { 0xFA25, 0x001F },
+ { 0xF804, 0x00FF },
+ { 0xF802, 0x0FFF },
+ /*{ 0x????, 0x???? },
+ { 0x????, 0x???? },
+ { 0x????, 0x???? }*/
+};
+
+static const uint16 reset_program_a_v1_or_v2[] = {
+ 0x0000
+};
+static const uint16 reset_program_b_v1_or_v2[] = {
+ 0x0010, 0xFE00, 0xA021, 0xFF00, 0x8111, 0x0009, 0x0CA4, 0x0114,
+ 0x0280, 0x04F8, 0xFE00, 0x6F25, 0x06E0, 0x0010, 0xFC00, 0x0121,
+ 0xFC00, 0x0225, 0xFE00, 0x7125, 0xFE00, 0x6D11, 0x03F0, 0xFE00,
+ 0x6E25, 0x0008, 0x00E0
+};
+
+static const struct chip_helper_reset_values reset_program_v1_or_v2[] =
+{
+ {
+ MAKE_GP(REGISTERS, 0x000C),
+ nelem(reset_program_a_v1_or_v2),
+ reset_program_a_v1_or_v2
+ },
+ {
+ MAKE_GP(MAC_PMEM, 0x000000),
+ nelem(reset_program_b_v1_or_v2),
+ reset_program_b_v1_or_v2
+ }
+};
+
+static const struct chip_map_address_t unifi_map_address_v1_v2[] =
+{
+ { 0xFE9F, 0xFE7B }, /* PM1_BANK_SELECT */
+ { 0xFE9E, 0xFE78 }, /* PM2_BANK_SELECT */
+ { 0xFE9D, 0xFE7E }, /* SHARED_DMEM_PAGE */
+ { 0xFE91, 0xFE90 }, /* PROC_SELECT */
+ { 0xFE8D, 0xFE8C }, /* STOP_STATUS */
+};
+
+static const struct chip_map_address_t unifi_map_address_v22_v23[] =
+{
+ { 0xF8F9, 0xF8AC }, /* GW1_CONFIG */
+ { 0xF8FA, 0xF8AD }, /* GW2_CONFIG */
+ { 0xF8FB, 0xF8AE }, /* GW3_CONFIG */
+ { 0xF830, 0xF81E }, /* PROC_SELECT */
+ { 0xF831, 0xF81F }, /* STOP_STATUS */
+ { 0xF8FC, 0xF8AF }, /* IO_LOG_ADDRESS */
+};
+
+static const struct chip_device_regs_t unifi_device_regs_null =
+{
+ 0xFE81, /* GBL_CHIP_VERSION */
+ 0x0000, /* GBL_MISC_ENABLES */
+ 0x0000, /* DBG_EMU_CMD */
+ {
+ 0x0000, /* HOST.DBG_PROC_SELECT */
+ 0x0000, /* HOST.DBG_STOP_STATUS */
+ 0x0000, /* HOST.WINDOW1_PAGE */
+ 0x0000, /* HOST.WINDOW2_PAGE */
+ 0x0000, /* HOST.WINDOW3_PAGE */
+ 0x0000 /* HOST.IO_LOG_ADDR */
+ },
+ {
+ 0x0000, /* SPI.DBG_PROC_SELECT */
+ 0x0000, /* SPI.DBG_STOP_STATUS */
+ 0x0000, /* SPI.WINDOW1_PAGE */
+ 0x0000, /* SPI.WINDOW2_PAGE */
+ 0x0000, /* SPI.WINDOW3_PAGE */
+ 0x0000 /* SPI.IO_LOG_ADDR */
+ },
+ 0x0000, /* DBG_RESET */
+ 0x0000, /* > DBG_RESET_VALUE */
+ 0x0000, /* DBG_RESET_WARN */
+ 0x0000, /* DBG_RESET_WARN_VALUE */
+ 0x0000, /* DBG_RESET_RESULT */
+ 0xFFE9, /* XAP_PCH */
+ 0xFFEA, /* XAP_PCL */
+ 0x0000, /* PROC_PC_SNOOP */
+ 0x0000, /* WATCHDOG_DISABLE */
+ 0x0000, /* MAILBOX0 */
+ 0x0000, /* MAILBOX1 */
+ 0x0000, /* MAILBOX2 */
+ 0x0000, /* MAILBOX3 */
+ 0x0000, /* SDIO_HOST_INT */
+ 0x0000, /* SHARED_IO_INTERRUPT */
+ 0x0000 /* SDIO HIP HANDSHAKE */
+};
+
+/* Bigfoot */
+static const struct chip_device_regs_t unifi_device_regs_v1 =
+{
+ 0xFE81, /* GBL_CHIP_VERSION */
+ 0xFE87, /* GBL_MISC_ENABLES */
+ 0xFE9C, /* DBG_EMU_CMD */
+ {
+ 0xFE90, /* HOST.DBG_PROC_SELECT */
+ 0xFE8C, /* HOST.DBG_STOP_STATUS */
+ 0xFE7B, /* HOST.WINDOW1_PAGE */
+ 0xFE78, /* HOST.WINDOW2_PAGE */
+ 0xFE7E, /* HOST.WINDOW3_PAGE */
+ 0x0000 /* HOST.IO_LOG_ADDR */
+ },
+ {
+ 0xFE91, /* SPI.DBG_PROC_SELECT */
+ 0xFE8D, /* SPI.DBG_STOP_STATUS */
+ 0xFE9F, /* SPI.WINDOW1_PAGE */
+ 0xFE9E, /* SPI.WINDOW2_PAGE */
+ 0xFE9D, /* SPI.WINDOW3_PAGE */
+ 0x0000 /* SPI.IO_LOG_ADDR */
+ },
+ 0xFE92, /* DBG_RESET */
+ 0x0001, /* > DBG_RESET_VALUE */
+ 0xFDA0, /* DBG_RESET_WARN (HOST_SELECT) */
+ 0x0000, /* DBG_RESET_WARN_VALUE */
+ 0xFE92, /* DBG_RESET_RESULT */
+ 0xFFE9, /* XAP_PCH */
+ 0xFFEA, /* XAP_PCL */
+ 0x0051, /* PROC_PC_SNOOP */
+ 0xFE70, /* WATCHDOG_DISABLE */
+ 0xFE6B, /* MAILBOX0 */
+ 0xFE6A, /* MAILBOX1 */
+ 0xFE69, /* MAILBOX2 */
+ 0xFE68, /* MAILBOX3 */
+ 0xFE67, /* SDIO_HOST_INT */
+ 0xFE65, /* SHARED_IO_INTERRUPT */
+ 0xFDE9 /* SDIO HIP HANDSHAKE */
+};
+
+/* Pumpkin */
+static const struct chip_device_regs_t unifi_device_regs_v2 =
+{
+ 0xFE81, /* GBL_CHIP_VERSION */
+ 0xFE87, /* GBL_MISC_ENABLES */
+ 0xFE9C, /* DBG_EMU_CMD */
+ {
+ 0xFE90, /* HOST.DBG_PROC_SELECT */
+ 0xFE8C, /* HOST.DBG_STOP_STATUS */
+ 0xFE7B, /* HOST.WINDOW1_PAGE */
+ 0xFE78, /* HOST.WINDOW2_PAGE */
+ 0xFE7E, /* HOST.WINDOW3_PAGE */
+ 0x0000 /* HOST.IO_LOG_ADDR */
+ },
+ {
+ 0xFE91, /* SPI.DBG_PROC_SELECT */
+ 0xFE8D, /* SPI.DBG_STOP_STATUS */
+ 0xFE9F, /* SPI.WINDOW1_PAGE */
+ 0xFE9E, /* SPI.WINDOW2_PAGE */
+ 0xFE9D, /* SPI.WINDOW3_PAGE */
+ 0x0000 /* SPI.IO_LOG_ADDR */
+ },
+ 0xFE92, /* DBG_RESET */
+ 0x0000, /* > DBG_RESET_VALUE */
+ 0xFDE9, /* DBG_RESET_WARN (TEST_FLASH_DATA - SHARED_MAILBOX2B) */
+ 0xFFFF, /* DBG_RESET_WARN_VALUE */
+ 0xFDE9, /* DBG_RESET_RESULT (TEST_FLASH_DATA) */
+ 0xFFE9, /* XAP_PCH */
+ 0xFFEA, /* XAP_PCL */
+ 0x0051, /* PROC_PC_SNOOP */
+ 0xFE70, /* WATCHDOG_DISABLE */
+ 0xFE6B, /* MAILBOX0 */
+ 0xFE6A, /* MAILBOX1 */
+ 0xFE69, /* MAILBOX2 */
+ 0xFE68, /* MAILBOX3 */
+ 0xFE67, /* SDIO_HOST_INT */
+ 0xFE65, /* SHARED_IO_INTERRUPT */
+ 0xFE69 /* SDIO HIP HANDSHAKE */
+};
+
+/* Cinderella */
+static const struct chip_device_regs_t unifi_device_regs_v22_v23 =
+{
+ 0xFE81, /* GBL_CHIP_VERSION */
+ 0xF84F, /* GBL_MISC_ENABLES */
+ 0xF81D, /* DBG_EMU_CMD */
+ {
+ 0xF81E, /* HOST.DBG_PROC_SELECT */
+ 0xF81F, /* HOST.DBG_STOP_STATUS */
+ 0xF8AC, /* HOST.WINDOW1_PAGE */
+ 0xF8AD, /* HOST.WINDOW2_PAGE */
+ 0xF8AE, /* HOST.WINDOW3_PAGE */
+ 0xF8AF /* HOST.IO_LOG_ADDR */
+ },
+ {
+ 0xF830, /* SPI.DBG_PROC_SELECT */
+ 0xF831, /* SPI.DBG_STOP_STATUS */
+ 0xF8F9, /* SPI.WINDOW1_PAGE */
+ 0xF8FA, /* SPI.WINDOW2_PAGE */
+ 0xF8FB, /* SPI.WINDOW3_PAGE */
+ 0xF8FC /* SPI.IO_LOG_ADDR */
+ },
+ 0xF82F, /* DBG_RESET */
+ 0x0001, /* > DBG_RESET_VALUE */
+ 0x0000, /* DBG_RESET_WARN */
+ 0x0000, /* DBG_RESET_WARN_VALUE */
+ 0xF82F, /* DBG_RESET_RESULT */
+ 0xFFE9, /* XAP_PCH */
+ 0xFFEA, /* XAP_PCL */
+ 0x001B, /* PROC_PC_SNOOP */
+ 0x0055, /* WATCHDOG_DISABLE */
+ 0xF84B, /* MAILBOX0 */
+ 0xF84C, /* MAILBOX1 */
+ 0xF84D, /* MAILBOX2 */
+ 0xF84E, /* MAILBOX3 */
+ 0xF92F, /* SDIO_HOST_INT */
+ 0xF92B, /* SDIO_FROMHOST_SCRTACH0 / SHARED_IO_INTERRUPT */
+ 0xF84D /* SDIO HIP HANDSHAKE (MAILBOX2) */
+};
+
+/* Program memory window on Bigfoot or Pumpkin. */
+static const struct window_shift_info_t prog_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] =
+{
+ { TRUE, 11, 0x0200 }, /* CODE RAM */
+ { TRUE, 11, 0x0000 }, /* FLASH */
+ { TRUE, 11, 0x0400 }, /* External SRAM */
+ { FALSE }, /* ROM */
+ { FALSE } /* SHARED */
+};
+
+/* Shared memory window on Bigfoot or Pumpkin. */
+static const struct window_shift_info_t shared_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] =
+{
+ { FALSE }, /* CODE RAM */
+ { FALSE }, /* FLASH */
+ { FALSE }, /* External SRAM */
+ { FALSE }, /* ROM */
+ { TRUE, 11, 0x0000 } /* SHARED */
+};
+
+/* One of the Gneric Windows on Cinderella / Anastasia. */
+static const struct window_shift_info_t generic_window_array_unifi_v22_v23[CHIP_HELPER_WT_COUNT] =
+{
+ { TRUE, 11, 0x3800 }, /* CODE RAM */
+ { FALSE }, /* FLASH */
+ { FALSE }, /* External SRAM */
+ { TRUE, 11, 0x2000 }, /* ROM */
+ { TRUE, 11, 0x0000 } /* SHARED */
+};
+
+/* The three windows on Bigfoot / Pumpkin. */
+static const struct window_info_t prog1_window_unifi_v1_v2 = { 0x0000, 0x2000, 0x0080, prog_window_array_unifi_v1_v2 };
+static const struct window_info_t prog2_window_unifi_v1_v2 = { 0x2000, 0x2000, 0x0000, prog_window_array_unifi_v1_v2 };
+static const struct window_info_t shared_window_unifi_v1_v2 = { 0x4000, 0x2000, 0x0000, shared_window_array_unifi_v1_v2 };
+
+/* The three windows on Cinderella / Anastasia. */
+static const struct window_info_t generic1_window_unifi_v22_v23 = { 0x0000, 0x2000, 0x0080, generic_window_array_unifi_v22_v23 };
+static const struct window_info_t generic2_window_unifi_v22_v23 = { 0x2000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 };
+static const struct window_info_t generic3_window_unifi_v22_v23 = { 0x4000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 };
+
+static const struct chip_device_desc_t chip_device_desc_null =
+{
+ { FALSE, 0x0000, 0x0000, 0x00 },
+ "",
+ "",
+ null_counted(), /* init */
+ null_counted(), /* reset_prog */
+ &unifi_device_regs_null, /* regs */
+ {
+ FALSE, /* has_flash */
+ FALSE, /* has_ext_sram */
+ FALSE, /* has_rom */
+ FALSE, /* has_bt */
+ FALSE, /* has_wlan */
+ },
+ null_counted(),
+ /* prog_offset */
+ {
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+ },
+ /* data_offset */
+ {
+ 0x0000 /* ram */
+ },
+ /* windows */
+ {
+ NULL,
+ NULL,
+ NULL
+ }
+};
+
+static const struct chip_device_desc_t unifi_device_desc_v1 =
+{
+ { FALSE, 0xf0ff, 0x1001, 0x01 }, /* BigFoot R01 */
+ "Bigfoot",
+ "UniFi-1",
+ counted(init_vals_v1), /* init */
+ counted(reset_program_v1_or_v2), /* reset_prog */
+ &unifi_device_regs_v1, /* regs */
+ {
+ TRUE, /* has_flash */
+ TRUE, /* has_ext_sram */
+ FALSE, /* has_rom */
+ FALSE, /* has_bt */
+ TRUE, /* has_wlan */
+ },
+ counted(unifi_map_address_v1_v2), /* map */
+ /* prog_offset */
+ {
+ 0x00100000, /* ram */
+ 0x00000000, /* rom (invalid) */
+ 0x00000000, /* flash */
+ 0x00200000, /* ext_ram */
+ },
+ /* data_offset */
+ {
+ 0x8000 /* ram */
+ },
+ /* windows */
+ {
+ &prog1_window_unifi_v1_v2,
+ &prog2_window_unifi_v1_v2,
+ &shared_window_unifi_v1_v2
+ }
+};
+
+static const struct chip_device_desc_t unifi_device_desc_v2 =
+{
+ { FALSE, 0xf0ff, 0x2001, 0x02 }, /* Pumpkin R02 */
+ "Pumpkin",
+ "UniFi-2",
+ counted(init_vals_v2), /* init */
+ counted(reset_program_v1_or_v2), /* reset_prog */
+ &unifi_device_regs_v2, /* regs */
+ {
+ TRUE, /* has_flash */
+ TRUE, /* has_ext_sram */
+ FALSE, /* has_rom */
+ FALSE, /* has_bt */
+ TRUE, /* has_wlan */
+ },
+ counted(unifi_map_address_v1_v2), /* map */
+ /* prog_offset */
+ {
+ 0x00100000, /* ram */
+ 0x00000000, /* rom (invalid) */
+ 0x00000000, /* flash */
+ 0x00200000, /* ext_ram */
+ },
+ /* data_offset */
+ {
+ 0x8000 /* ram */
+ },
+ /* windows */
+ {
+ &prog1_window_unifi_v1_v2,
+ &prog2_window_unifi_v1_v2,
+ &shared_window_unifi_v1_v2
+ }
+};
+
+static const struct chip_device_desc_t unifi_device_desc_v3 =
+{
+ { FALSE, 0xf0ff, 0x3001, 0x02 }, /* Pumpkin R03 */
+ "Pumpkin",
+ "UniFi-3",
+ counted(init_vals_v2), /* init */
+ counted(reset_program_v1_or_v2), /* reset_prog */
+ &unifi_device_regs_v2, /* regs */
+ {
+ TRUE, /* has_flash */
+ TRUE, /* has_ext_sram */
+ FALSE, /* has_rom */
+ FALSE, /* has_bt */
+ TRUE, /* has_wlan */
+ },
+ counted(unifi_map_address_v1_v2), /* map */
+ /* prog_offset */
+ {
+ 0x00100000, /* ram */
+ 0x00000000, /* rom (invalid) */
+ 0x00000000, /* flash */
+ 0x00200000, /* ext_ram */
+ },
+ /* data_offset */
+ {
+ 0x8000 /* ram */
+ },
+ /* windows */
+ {
+ &prog1_window_unifi_v1_v2,
+ &prog2_window_unifi_v1_v2,
+ &shared_window_unifi_v1_v2
+ }
+};
+
+static const struct chip_device_desc_t unifi_device_desc_v22 =
+{
+ { FALSE, 0x00ff, 0x0022, 0x07 }, /* Cinderella */
+ "Cinderella",
+ "UniFi-4",
+ counted(init_vals_v22_v23), /* init */
+ null_counted(), /* reset_prog */
+ &unifi_device_regs_v22_v23, /* regs */
+ {
+ FALSE, /* has_flash */
+ FALSE, /* has_ext_sram */
+ TRUE, /* has_rom */
+ FALSE, /* has_bt */
+ TRUE, /* has_wlan */
+ },
+ counted(unifi_map_address_v22_v23), /* map */
+ /* prog_offset */
+ {
+ 0x00C00000, /* ram */
+ 0x00000000, /* rom */
+ 0x00000000, /* flash (invalid) */
+ 0x00000000, /* ext_ram (invalid) */
+ },
+ /* data_offset */
+ {
+ 0x8000 /* ram */
+ },
+ /* windows */
+ {
+ &generic1_window_unifi_v22_v23,
+ &generic2_window_unifi_v22_v23,
+ &generic3_window_unifi_v22_v23
+ }
+};
+
+static const struct chip_device_desc_t unifi_device_desc_v23 =
+{
+ { FALSE, 0x00ff, 0x0023, 0x08 }, /* Anastasia */
+ "Anastasia",
+ "OmniUniEveryFi (5)",
+ counted(init_vals_v22_v23), /* init */
+ null_counted(), /* reset_prog */
+ &unifi_device_regs_v22_v23, /* regs */
+ {
+ FALSE, /* has_flash */
+ FALSE, /* has_ext_sram */
+ TRUE, /* has_rom */
+ TRUE, /* has_bt */
+ TRUE, /* has_wlan */
+ },
+ counted(unifi_map_address_v22_v23),
+ /* prog_offset */
+ {
+ 0x00C00000, /* ram */
+ 0x00000000, /* rom */
+ 0x00000000, /* flash (invalid) */
+ 0x00000000, /* ext_sram (invalid) */
+ },
+ /* data_offset */
+ {
+ 0x8000 /* ram */
+ },
+ /* windows */
+ {
+ &generic1_window_unifi_v22_v23,
+ &generic2_window_unifi_v22_v23,
+ &generic3_window_unifi_v22_v23
+ }
+};
+
+/* This is the list of all chips that we know about. I'm
+ assuming that the order here will be important - we
+ might have multiple entries witrh the same SDIO id for
+ instance. The first one in this list will be the one
+ that is returned if a search is done on only that id.
+ The client will then have to call GetVersionXXX again
+ but with more detailed info.
+
+ I don't know if we need to signal this up to the client
+ in some way?
+
+ (We get the SDIO id before we know anything else about
+ the chip. We might not be able to read any of the other
+ registers at first, but we still need to know about the
+ chip). */
+static const struct chip_device_desc_t *chip_ver_to_desc[] =
+{
+ &unifi_device_desc_v1, /* BigFoot R01 */
+ &unifi_device_desc_v2, /* Pumpkin R02 */
+ &unifi_device_desc_v3, /* Pumpkin R03 */
+ &unifi_device_desc_v22, /* Cinderella */
+ &unifi_device_desc_v23, /* Anastasia */
+};
+
+ChipDescript *ChipHelper_GetVersionSdio(uint8 sdio_ver)
+{
+ unsigned int i;
+
+ for (i=0; i<nelem(chip_ver_to_desc); i++)
+ {
+ if (chip_ver_to_desc[i]->chip_version.sdio == sdio_ver)
+ {
+ return chip_ver_to_desc[i];
+ }
+ }
+
+ return &chip_device_desc_null;
+}
+
+ChipDescript *ChipHelper_GetVersionAny(uint16 from_FF9A, uint16 from_FE81)
+{
+ unsigned int i;
+
+ if ((from_FF9A & 0xFF00) != 0)
+ {
+ for (i=0; i<nelem(chip_ver_to_desc); i++)
+ {
+ if (chip_ver_to_desc[i]->chip_version.pre_bc7 &&
+ ((from_FF9A & chip_ver_to_desc[i]->chip_version.mask) ==
+ chip_ver_to_desc[i]->chip_version.result))
+ {
+ return chip_ver_to_desc[i];
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<nelem(chip_ver_to_desc); i++)
+ {
+ if (!chip_ver_to_desc[i]->chip_version.pre_bc7 &&
+ ((from_FE81 & chip_ver_to_desc[i]->chip_version.mask) ==
+ chip_ver_to_desc[i]->chip_version.result))
+ {
+ return chip_ver_to_desc[i];
+ }
+ }
+ }
+
+ return &chip_device_desc_null;
+}
+
+ChipDescript *ChipHelper_GetVersionUniFi(uint16 ver)
+{
+ return ChipHelper_GetVersionAny(0x0000, ver);
+}
+
+ChipDescript *ChipHelper_Null()
+{
+ return &chip_device_desc_null;
+}
+
+ChipDescript *ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age bc_age, uint16 version)
+{
+ if (bc_age == chip_helper_bluecore_pre_bc7)
+ return ChipHelper_GetVersionAny(version, 0x0000);
+ else
+ return ChipHelper_GetVersionAny(0x0000, version);
+}
+
+/* Expand the DEF0 functions into simple code to return the
+ correct thing. The DEF1 functions expand to nothing in
+ this X macro expansion. */
+#define CHIP_HELPER_DEF0_C_DEF(ret_type, name, info) \
+ret_type ChipHelper_ ## name(ChipDescript *chip_help) \
+{ \
+ return chip_help->info; \
+}
+#define CHIP_HELPER_DEF1_C_DEF(ret_type, name, type1)
+
+CHIP_HELPER_LIST(C_DEF)
+
+/*
+ * Map register addresses between HOST and SPI access.
+ */
+uint16 ChipHelper_MapAddress_SPI2HOST(ChipDescript *chip_help, uint16 addr)
+{
+ unsigned int i;
+ for (i=0; i<chip_help->map.len; i++)
+ if (chip_help->map.vals[i].spi == addr)
+ return chip_help->map.vals[i].host;
+ return addr;
+}
+uint16 ChipHelper_MapAddress_HOST2SPI(ChipDescript *chip_help, uint16 addr)
+{
+ unsigned int i;
+ for (i=0; i<chip_help->map.len; i++)
+ if (chip_help->map.vals[i].host == addr)
+ return chip_help->map.vals[i].spi;
+ return addr;
+}
+
+/* The address returned by this function is the start of the
+ window in the address space, that is where we can start
+ accessing data from. If a section of the window at the
+ start is unusable because something else is cluttering up
+ the address map then that is taken into account and this
+ function returns that address justt past that. */
+uint16 ChipHelper_WINDOW_ADDRESS(ChipDescript *chip_help,
+ enum chip_helper_window_index window)
+{
+ if (window >= 0 &&
+ window < CHIP_HELPER_WINDOW_COUNT &&
+ chip_help->windows[window] != NULL)
+ return chip_help->windows[window]->address + chip_help->windows[window]->blocked;
+ return 0;
+}
+
+/* This returns the size of the window minus any blocked section */
+uint16 ChipHelper_WINDOW_SIZE(ChipDescript *chip_help,
+ enum chip_helper_window_index window)
+{
+ if (window >= 0 &&
+ window < CHIP_HELPER_WINDOW_COUNT &&
+ chip_help->windows[window] != NULL)
+ return chip_help->windows[window]->size - chip_help->windows[window]->blocked;
+ return 0;
+}
+
+/* Get the register writes we should do to make sure that
+ the chip is running with most clocks on. */
+unsigned int ChipHelper_ClockStartupSequence(ChipDescript *chip_help,
+ const struct chip_helper_init_values **val)
+{
+ *val = chip_help->init.vals;
+ return chip_help->init.len;
+}
+
+/* Get the set of values tat we should write to the chip to perform a reset. */
+unsigned int ChipHelper_HostResetSequence(ChipDescript *chip_help,
+ const struct chip_helper_reset_values **val)
+{
+ *val = chip_help->reset_prog.vals;
+ return chip_help->reset_prog.len;
+}
+
+/* Decode a windowed access to the chip. */
+int ChipHelper_DecodeWindow(ChipDescript *chip_help,
+ enum chip_helper_window_index window,
+ enum chip_helper_window_type type,
+ uint32 offset,
+ uint16 *page, uint16 *addr, uint32 *len)
+{
+ const struct window_info_t *win;
+ const struct window_shift_info_t *mode;
+ uint16 of, pg;
+
+ if (window < 0 || window >= CHIP_HELPER_WINDOW_COUNT)
+ return FALSE;
+ if ((win = chip_help->windows[window]) == NULL)
+ return FALSE;
+ if (type < 0 || type >= CHIP_HELPER_WT_COUNT)
+ return FALSE;
+ if ((mode = &win->mode[type]) == NULL)
+ return FALSE;
+ if (!mode->allowed)
+ return FALSE;
+
+ pg = (uint16)(offset >> mode->page_shift) + mode->page_offset;
+ of = (uint16)(offset & ((1 << mode->page_shift) - 1));
+ /* If 'blocked' is zero this does nothing, else decrease
+ the page register and increase the offset until we aren't
+ in the blocked region of the window. */
+ while (of < win->blocked)
+ {
+ of += 1 << mode->page_shift;
+ pg--;
+ }
+ *page = pg;
+ *addr = win->address + of;
+ *len = win->size - of;
+ return TRUE;
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.h b/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.h
new file mode 100644
index 0000000..6f4c625
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper.h
@@ -0,0 +1,452 @@
+/*
+FILE
+ chiphelper.h
+
+DESCRIPTION
+ This file contains an interface to a data base that contains
+ all osrts of information about different CSR chips. It doesn't
+ contain any code that "does" anything, it just returns numbers,
+ strings and bools that tell you things. It is menat to be used
+ by host tools (via pttransport) and maybe by device drivers.
+
+ There is a C interface and a C++ interface. The C++ code is a
+ wrapper around the C. This is so that people using C can use
+ this. Please be careful not to break this.
+
+ You should not need to include any other CSR specific header files
+ to get this to work. This is good, we wnat to try to limit the
+ distribution of things like io_defs.h, and the number of different
+ copies of this file has now spiralled out of control (it should
+ never have been allowed in the host tree).
+
+ HERE:
+ At the moment so information about the windows is assumed. Maybe
+ it should all be exteneded so you have to ask which window to use
+ for what. (On bigfoot some windows only see some things).
+
+ HERE:
+ Longer descriptions of all of this would help greatly.
+*/
+#ifndef CHIPHELPER_H__
+#define CHIPHELPER_H__
+
+#ifdef __KERNEL__
+#include "driver/unifi_types.h"
+#else
+#include "common/types.h"
+#include "common/macros.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The age of the BlueCore chip. This is probably not useful, if
+ you know the age then you can probably work out the version directly. */
+enum chip_helper_bluecore_age
+{
+ chip_helper_bluecore_pre_bc7,
+ chip_helper_bluecore_bc7_or_later
+};
+
+/* We support up to three windowed regions at the moment.
+ Don't reorder these - they're used to index into an array. */
+enum chip_helper_window_index
+{
+ CHIP_HELPER_WINDOW_1,
+ CHIP_HELPER_WINDOW_2,
+ CHIP_HELPER_WINDOW_3,
+ CHIP_HELPER_WINDOW_COUNT
+};
+
+/* These are the things that we can access through a window.
+ Don't reorder these - they're used to index into an array. */
+enum chip_helper_window_type
+{
+ CHIP_HELPER_WT_CODE_RAM,
+ CHIP_HELPER_WT_FLASH,
+ CHIP_HELPER_WT_EXT_SRAM,
+ CHIP_HELPER_WT_ROM,
+ CHIP_HELPER_WT_SHARED,
+ CHIP_HELPER_WT_COUNT
+};
+
+/* Commands to stop and start the XAP */
+enum chip_helper_dbg_emu_cmd_enum
+{
+ CHIP_HELPER_DBG_EMU_CMD_XAP_STEP_MASK = 0x0001,
+ CHIP_HELPER_DBG_EMU_CMD_XAP_RUN_B_MASK = 0x0002,
+ CHIP_HELPER_DBG_EMU_CMD_XAP_BRK_MASK = 0x0004,
+ CHIP_HELPER_DBG_EMU_CMD_XAP_WAKEUP_MASK = 0x0008
+};
+
+/* Codes to disable the watchdog */
+enum chip_helper_watchdog_disable_enum
+{
+ CHIP_HELPER_WATCHDOG_DISABLE_CODE1 = 0x6734,
+ CHIP_HELPER_WATCHDOG_DISABLE_CODE2 = 0xD6BF,
+ CHIP_HELPER_WATCHDOG_DISABLE_CODE3 = 0xC31E
+};
+
+/* Other bits have changed between versions */
+enum chip_helper_gbl_misc_enum
+{
+ CHIP_HELPER_GBL_MISC_SPI_STOP_OUT_EN_MASK = 0x0001,
+ CHIP_HELPER_GBL_MISC_MMU_INIT_DONE_MASK = 0x0004
+};
+
+/* How to select the different CPUs */
+enum chip_helper_dbg_proc_sel_enum
+{
+ CHIP_HELPER_DBG_PROC_SEL_MAC = 0,
+ CHIP_HELPER_DBG_PROC_SEL_PHY = 1,
+ CHIP_HELPER_DBG_PROC_SEL_BT = 2,
+ CHIP_HELPER_DBG_PROC_SEL_NONE = 2,
+ CHIP_HELPER_DBG_PROC_SEL_BOTH = 3
+};
+
+/* These are the only registers that we have to know the
+ address of before we know the chip version. */
+enum chip_helper_fixed_registers
+{
+ /* This is the address of GBL_CHIP_VERISON on BC7,
+ Bigfoot, Pumpkin, Cinderella, Anastasia and
+ anything later than that. */
+ CHIP_HELPER_UNIFI_GBL_CHIP_VERSION = 0xFE81,
+
+ CHIP_HELPER_OLD_BLUECORE_GBL_CHIP_VERSION = 0xFF9A,
+
+ /* This isn't used at the moment (but might be needed
+ to distinguish the BLueCore sub version?) */
+ /* CHIP_HELPER_OLD_BLUECORE_ANA_VERSION_ID = 0xFF7D */
+};
+
+/* Address-value pairs for defining initialisation values */
+struct chip_helper_init_values
+{
+ uint16 addr;
+ uint16 value;
+};
+
+/* A block of data that should be written to the device */
+struct chip_helper_reset_values
+{
+ uint32 gp_address;
+ unsigned int len;
+ const uint16 *data;
+};
+
+/*
+ * This is the C API.
+ */
+
+/* opaque type */
+typedef const struct chip_device_desc_t ChipDescript;
+
+/* Return a NULL descriptor */
+ChipDescript *ChipHelper_Null(void);
+
+/* This should get the correct version for any CSR chip.
+ The two parameters are what is read from addresses
+ 0xFF9A and 0xFE81 (OLD_BLUECORE_GBL_CHIP_VERSION and
+ UNIFI_GBL_CHIP_VERSION). These should give a unique identity
+ for most (all?) chips.
+
+ FF9A is the old GBL_CHIP_VERSION register. If the high
+ eight bits are zero then the chip is a new (BC7 +) one
+ and FE81 is the _new_ GBL_CHIP_VERSION register. */
+ChipDescript *ChipHelper_GetVersionAny(uint16 from_FF9A, uint16 from_FE81);
+
+/* The chip is a UniFi, but we don't know which type
+ The parameter is the value of UNIFI_GBL_CHIP_VERSION (0xFE81) */
+ChipDescript *ChipHelper_GetVersionUniFi(uint16 version);
+
+/* This gets the version from the SDIO device id. This only
+ gives quite a coarse grained version, so we should update once
+ we hav access to the function N registers. */
+ChipDescript *ChipHelper_GetVersionSdio(uint8 sdio_version);
+
+/* The chip is some sort of BlueCore. If "age" is "pre_bc7" then
+ "version" is what was read from FF9A. If "age" is bc7_or_later
+ then "version" is read from FE81. If we don't know if we're pre
+ or post BC7 then we should use "GetVersionAny". */
+ChipDescript *ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age age,
+ uint16 version);
+
+/* The main functions of this class are built with an X macro. This
+ means we can generate the C and C++ versions from the same source
+ without the two diverging.
+
+ The DEF0 functions are simple and take no parameters. The first
+ parameter to the macro is the return type. The second parameter
+ is the function anme and the third parameter is where to get the
+ info from (this is hidden from the user).
+
+ The DEF1 functions take one parameter. This time the third macro
+ parameter is the type of this parameter. The bodies of these
+ functions are hand written. */
+#define CHIP_HELPER_LIST(m) \
+ CHIP_HELPER_DEF0(m, (const char *, FriendlyName, friendly_name)) \
+ CHIP_HELPER_DEF0(m, (const char *, MarketingName, marketing_name)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_EMU_CMD, regs->dbg_emu_cmd)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_HOST_PROC_SELECT, regs->host.dbg_proc_select)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_HOST_STOP_STATUS, regs->host.dbg_stop_status)) \
+ CHIP_HELPER_DEF0(m, (uint16, HOST_WINDOW1_PAGE, regs->host.window1_page)) \
+ CHIP_HELPER_DEF0(m, (uint16, HOST_WINDOW2_PAGE, regs->host.window2_page)) \
+ CHIP_HELPER_DEF0(m, (uint16, HOST_WINDOW3_PAGE, regs->host.window3_page)) \
+ CHIP_HELPER_DEF0(m, (uint16, HOST_IO_LOG_ADDR, regs->host.io_log_addr)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_SPI_PROC_SELECT, regs->spi.dbg_proc_select)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_SPI_STOP_STATUS, regs->spi.dbg_stop_status)) \
+ CHIP_HELPER_DEF0(m, (uint16, SPI_WINDOW1_PAGE, regs->spi.window1_page)) \
+ CHIP_HELPER_DEF0(m, (uint16, SPI_WINDOW2_PAGE, regs->spi.window2_page)) \
+ CHIP_HELPER_DEF0(m, (uint16, SPI_WINDOW3_PAGE, regs->spi.window3_page)) \
+ CHIP_HELPER_DEF0(m, (uint16, SPI_IO_LOG_ADDR, regs->spi.io_log_addr)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_RESET, regs->dbg_reset)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_RESET_VALUE, regs->dbg_reset_value)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_RESET_WARN, regs->dbg_reset_warn)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_RESET_WARN_VALUE, regs->dbg_reset_warn_value)) \
+ CHIP_HELPER_DEF0(m, (uint16, DBG_RESET_RESULT, regs->dbg_reset_result)) \
+ CHIP_HELPER_DEF0(m, (uint16, WATCHDOG_DISABLE, regs->watchdog_disable)) \
+ CHIP_HELPER_DEF0(m, (uint16, PROC_PC_SNOOP, regs->proc_pc_snoop)) \
+ CHIP_HELPER_DEF0(m, (uint16, GBL_CHIP_VERSION, regs->gbl_chip_version)) \
+ CHIP_HELPER_DEF0(m, (uint16, GBL_MISC_ENABLES, regs->gbl_misc_enables)) \
+ CHIP_HELPER_DEF0(m, (uint16, XAP_PCH, regs->xap_pch)) \
+ CHIP_HELPER_DEF0(m, (uint16, XAP_PCL, regs->xap_pcl)) \
+ CHIP_HELPER_DEF0(m, (uint16, MAILBOX0, regs->mailbox0)) \
+ CHIP_HELPER_DEF0(m, (uint16, MAILBOX1, regs->mailbox1)) \
+ CHIP_HELPER_DEF0(m, (uint16, MAILBOX2, regs->mailbox2)) \
+ CHIP_HELPER_DEF0(m, (uint16, MAILBOX3, regs->mailbox3)) \
+ CHIP_HELPER_DEF0(m, (uint16, SDIO_HIP_HANDSHAKE, regs->sdio_hip_handshake)) \
+ CHIP_HELPER_DEF0(m, (uint16, SDIO_HOST_INT, regs->sdio_host_int)) \
+ CHIP_HELPER_DEF0(m, (uint16, SHARED_IO_INTERRUPT, regs->shared_io_interrupt)) \
+ CHIP_HELPER_DEF0(m, (uint32, PROGRAM_MEMORY_RAM_OFFSET, prog_offset.ram)) \
+ CHIP_HELPER_DEF0(m, (uint32, PROGRAM_MEMORY_ROM_OFFSET, prog_offset.rom)) \
+ CHIP_HELPER_DEF0(m, (uint32, PROGRAM_MEMORY_FLASH_OFFSET, prog_offset.flash)) \
+ CHIP_HELPER_DEF0(m, (uint32, PROGRAM_MEMORY_EXT_SRAM_OFFSET, prog_offset.ext_sram)) \
+ CHIP_HELPER_DEF0(m, (uint16, DATA_MEMORY_RAM_OFFSET, data_offset.ram)) \
+ CHIP_HELPER_DEF0(m, (int, HasFlash, bools.has_flash)) \
+ CHIP_HELPER_DEF0(m, (int, HasExtSram, bools.has_ext_sram)) \
+ CHIP_HELPER_DEF0(m, (int, HasRom, bools.has_rom)) \
+ CHIP_HELPER_DEF0(m, (int, HasBt, bools.has_bt)) \
+ CHIP_HELPER_DEF0(m, (int, HasWLan, bools.has_wlan)) \
+ CHIP_HELPER_DEF1(m, (uint16, WINDOW_ADDRESS, enum chip_helper_window_index)) \
+ CHIP_HELPER_DEF1(m, (uint16, WINDOW_SIZE, enum chip_helper_window_index)) \
+ CHIP_HELPER_DEF1(m, (uint16, MapAddress_SPI2HOST, uint16)) \
+ CHIP_HELPER_DEF1(m, (uint16, MapAddress_HOST2SPI, uint16)) \
+ CHIP_HELPER_DEF1(m, (unsigned int, ClockStartupSequence, const struct chip_helper_init_values **)) \
+ CHIP_HELPER_DEF1(m, (unsigned int, HostResetSequence, const struct chip_helper_reset_values **))
+
+/* Some magic to help the expansion */
+#define CHIP_HELPER_DEF0(a, b) \
+ CHIP_HELPER_DEF0_##a b
+#define CHIP_HELPER_DEF1(a, b) \
+ CHIP_HELPER_DEF1_##a b
+
+/* Macros so that when we expand the list we get "C" function prototypes. */
+#define CHIP_HELPER_DEF0_C_DEC(ret_type, name, info) \
+ ret_type ChipHelper_ ## name(ChipDescript *);
+#define CHIP_HELPER_DEF1_C_DEC(ret_type, name, type1) \
+ ret_type ChipHelper_ ## name(ChipDescript *, type1);
+
+CHIP_HELPER_LIST(C_DEC)
+
+/* FriendlyName
+ MarketingName
+
+ These two functions return human readable strings that describe
+ the chip. FriendlyName returns something that a siftware engineer
+ at CSR might understand. MarketingName returns something more like
+ an external name for a CSR chip.
+*/
+/* DBG_EMU_CMD
+ WATCHDOG_DISABLE
+ PROC_PC_SNOOP
+ GBL_CHIP_VERSION
+ XAP_PCH
+ XAP_PCL
+
+ These registers are used to control the XAPs.
+*/
+/* DBG_HOST_PROC_SELECT DBG_HOST_STOP_STATUS
+ HOST_WINDOW1_PAGE HOST_WINDOW2_PAGE HOST_WINDOW3_PAGE
+ HOST_IO_LOG_ADDR
+ DBG_SPI_PROC_SELECT DBG_SPI_STOP_STATUS
+ SPI_WINDOW1_PAGE SPI_WINDOW2_PAGE SPI_WINDOW3_PAGE
+ SPI_IO_LOG_ADDR
+
+ These register are used to control the XAPs and the memory
+ windows, normally while debugging the code on chip. There
+ are two versons of these registers, one for access via SPI
+ and another for access via the host interface.
+*/
+/* DBG_RESET
+ DBG_RESET_VALUE
+ DBG_RESET_WARN
+ DBG_RESET_WARN_VALUE
+ DBG_RESET_RESULT
+
+ These registers are used to reset the XAP. This can be
+ quite complex for some chips. If DBG_RESET_WARN is non
+ zero the DBG_RESET_WARN_VALUE should be written to address
+ DBG_RESET_WARN before the reset is perfeormed. DBG_RESET_VALUE
+ should then be wrritten to DBG_RESET to make the reset happen.
+ The DBG_RESET_RESULT register should contain 0 if the reset
+ was successful.
+*/
+/* GBL_MISC_ENABLES
+
+ This register controls some special chip features. It
+ should be used with care is it changes quite a lot between
+ chip versions.
+*/
+/* MAILBOX0
+ MAILBOX1
+ MAILBOX2
+ MAILBOX3
+
+ The mailbox register are for communication between the host
+ and the firmware. There use is described in part by the host
+ interface protcol specifcation.
+*/
+/* SDIO_HIP_HANDSHAKE
+
+ This is one of the more important SDIO HIP registers. On some
+ chips it has the same value as one of the mailbox registers
+ and on other chips it is different.
+*/
+/* SDIO_HOST_INT
+ SHARED_IO_INTERRUPT
+
+ These registers are used by some version of the host interface
+ protocol specification. There names should probably be changed
+ to hide the registers and to erxpose the functions more.
+*/
+/* PROGRAM_MEMORY_RAM_OFFSET
+ PROGRAM_MEMORY_ROM_OFFSET
+ PROGRAM_MEMORY_FLASH_OFFSET
+ PROGRAM_MEMORY_EXT_SRAM_OFFSET
+ DATA_MEMORY_RAM_OFFSET
+
+ These are constants that describe the offset of the different
+ memory types in the two different address spaces.
+*/
+/* HasFlash HasExtSram HasRom
+ HasBt HasWLan
+
+ These are a set of bools describing the chip.
+*/
+/* WINDOW_ADDRESS WINDOW_SIZE
+
+ These two function return the size and address of the windows.
+ The address is the address of the lowest value in the address
+ map that is part of the window and the size is the number of
+ visible words.
+
+ Some of the windows have thier lowest portion covered by
+ registers. For these windows address is the first address
+ after the registers and size is the siave exculding the part
+ covered by registers.
+*/
+/* MapAddress_SPI2HOST
+ MapAddress_HOST2SPI
+
+ The debugging interface is duplicated on UniFia nd later chips
+ so that there are two versions - one over the SPI interaface and
+ the other over the SDIO interface. These functions map the
+ registers between these two interfaces.
+*/
+/* ClockStartupSequence
+
+ This function returns the list of registers value pairs that
+ should be forced into UniFi to enable SPI communication. This
+ set of registers is not needed if the firmware is running, but
+ will be needed if the device is being booted from cold. These
+ register writes enable the clocks and setup the PLL to a basic
+ working state. SPI access might be unreliable until these writes
+ have occured (And they may take mulitple goes).
+*/
+/* HostResetSequence
+
+ This is a bit of a mess. It returns a number of chunks of data
+ and generic pointers. All of the XAPs should be stopped. The
+ data should be written to the generic pointers. The instruction
+ pointer for the MAC should then be set to the start of program
+ memory and then the MAC should be "go"d. This will reset the
+ chip in a reliable and ordaly manner without resetting the SDIO
+ interface. It is therefore not needed if the chip is being
+ accessed by the SPI interface (the DBG_RESET_ mechanism can be
+ used instead).
+*/
+
+/* The Decode Window function is more complex. For the window
+ 'window' it tries to return the address and page register
+ value needed to see offset 'offset' of memory type 'type'.
+
+ It return 1 on success and 0 on failure. 'page' is what
+ should be written to the page register. 'addr' is the
+ address in the XAPs 16 address map to read from. 'len'
+ is the length that we can read without having to change
+ the page registers. */
+int ChipHelper_DecodeWindow(ChipDescript *,
+ enum chip_helper_window_index window,
+ enum chip_helper_window_type type,
+ uint32 offset,
+ uint16 *page, uint16 *addr, uint32 *len);
+
+#ifdef __cplusplus
+/* Close the extern "C" */
+}
+
+/*
+ * This is the C++ API.
+ */
+
+class ChipHelper
+{
+public:
+ /* If this constructor is used then a GetVersionXXX function
+ should be called next. */
+ ChipHelper();
+
+ /* copy constructor */
+ ChipHelper(ChipDescript *desc);
+
+ /* The default constructor assume a BC7 / Bigfoot series chip
+ and that the number given is the value of UNIFI_GBL_CHIP_VERSION
+ (0xFE81) */
+ ChipHelper(uint16 version);
+
+ /* This returns the C interface magic token from a C++ instance. */
+ ChipDescript *GetDescript() const { return m_desc; };
+
+ /* Clear out theis class (set it to the null token). */
+ void ClearVersion();
+
+ /* Load this class with data for a specific chip. */
+ void GetVersionAny(uint16 from_FF9A, uint16 from_FE81);
+ void GetVersionUniFi(uint16 version);
+ void GetVersionBlueCore(chip_helper_bluecore_age age, uint16 version);
+ void GetVersionSdio(uint8 sdio_version);
+
+ /* Helpers to build the definitions of the member functions. */
+#define CHIP_HELPER_DEF0_CPP_DEC(ret_type, name, info) \
+ ret_type name() const;
+#define CHIP_HELPER_DEF1_CPP_DEC(ret_type, name, type1) \
+ ret_type name(type1) const;
+
+ CHIP_HELPER_LIST(CPP_DEC)
+
+
+ /* The DecodeWindow function, see the description of the C version. */
+ int DecodeWindow(chip_helper_window_index window,
+ chip_helper_window_type type,
+ uint32 offset,
+ uint16 &page, uint16 &addr, uint32 &len) const;
+
+private:
+ ChipDescript *m_desc;
+};
+
+#endif /* __cplusplus */
+
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper_private.h b/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper_private.h
new file mode 100644
index 0000000..12aa279
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/chiphelper_private.h
@@ -0,0 +1,194 @@
+#ifndef CHIPHELPER_PRIVATE_H__
+#define CHIPHELPER_PRIVATE_H__
+
+#include "chiphelper.h"
+#ifdef __KERNEL__
+#include "driver/unifi_types.h"
+#else
+#include "common/types.h"
+#include "common/macros.h"
+#endif
+
+/* This GP stuff should be somewhere else? */
+
+/* Memory spaces encoded in top byte of Generic Pointer type */
+#define UNIFI_SH_DMEM 0x01 /* Shared Data Memory */
+#define UNIFI_EXT_FLASH 0x02 /* External FLASH */
+#define UNIFI_EXT_SRAM 0x03 /* External SRAM */
+#define UNIFI_REGISTERS 0x04 /* Registers */
+#define UNIFI_PHY_DMEM 0x10 /* PHY Data Memory */
+#define UNIFI_PHY_PMEM 0x11 /* PHY Program Memory */
+#define UNIFI_PHY_ROM 0x12 /* PHY ROM */
+#define UNIFI_MAC_DMEM 0x20 /* MAC Data Memory */
+#define UNIFI_MAC_PMEM 0x21 /* MAC Program Memory */
+#define UNIFI_MAC_ROM 0x22 /* MAC ROM */
+#define UNIFI_BT_DMEM 0x30 /* BT Data Memory */
+#define UNIFI_BT_PMEM 0x31 /* BT Program Memory */
+#define UNIFI_BT_ROM 0x32 /* BT ROM */
+
+#define MAKE_GP(R, O) (((UNIFI_ ## R) << 24) | (O))
+#define GP_OFFSET(GP) ((GP) & 0xFFFFFF)
+#define GP_SPACE(GP) (((GP) >> 24) & 0xFF)
+
+
+// Address value pairs
+struct val_array_t
+{
+ unsigned int len;
+ const struct chip_helper_init_values *vals;
+};
+
+// Just a (counted) uint16 array
+struct data_array_t
+{
+ unsigned int len;
+ const uint16 *vals;
+};
+
+struct reset_prog_t
+{
+ unsigned int len;
+ const struct chip_helper_reset_values *vals;
+};
+
+// The addresses of registers that are equivalent but on
+// different host transports.
+struct chip_map_address_t
+{
+ uint16 spi, host;
+};
+
+struct map_array_t
+{
+ unsigned int len;
+ const struct chip_map_address_t *vals;
+};
+
+struct chip_device_regs_per_transport_t
+{
+ uint16 dbg_proc_select;
+ uint16 dbg_stop_status;
+ uint16 window1_page; /* PROG_PMEM1 or GW1 */
+ uint16 window2_page; /* PROG_PMEM2 or GW2 */
+ uint16 window3_page; /* SHARED or GW3 */
+ uint16 io_log_addr;
+};
+
+struct chip_device_regs_t
+{
+ uint16 gbl_chip_version;
+ uint16 gbl_misc_enables;
+ uint16 dbg_emu_cmd;
+ struct chip_device_regs_per_transport_t host;
+ struct chip_device_regs_per_transport_t spi;
+ uint16 dbg_reset;
+ uint16 dbg_reset_value;
+ uint16 dbg_reset_warn;
+ uint16 dbg_reset_warn_value;
+ uint16 dbg_reset_result;
+ uint16 xap_pch;
+ uint16 xap_pcl;
+ uint16 proc_pc_snoop;
+ uint16 watchdog_disable;
+ uint16 mailbox0;
+ uint16 mailbox1;
+ uint16 mailbox2;
+ uint16 mailbox3;
+ uint16 sdio_host_int;
+ uint16 shared_io_interrupt;
+ uint16 sdio_hip_handshake;
+};
+
+// If allowed is false then this window does not provide this
+// type of access.
+// This describes how addresses should be shifted to make the
+// "page" address. The address is shifted left by 'page_shift'
+// and then has 'page_offset' added. This value should then be
+// written to the page register.
+struct window_shift_info_t
+{
+ int allowed;
+ unsigned int page_shift;
+ uint16 page_offset;
+};
+
+/* Each window has an address and size. These are obvious. It then
+ has a description for each type of memory that might be accessed
+ through it. There might also be a start to the offset of the window.
+ This means that that number of addresses at the start of the window
+ are unusable. */
+struct window_info_t
+{
+ uint16 address;
+ uint16 size;
+ uint16 blocked;
+ const struct window_shift_info_t *mode;
+};
+
+// If GBL_CHIP_VERSION and'ed with 'mask' and is equal to 'result'
+// then this is the correct set of info. If pre_bc7 is true then the
+// address of GBL_CHIP_VERSION is FF9A, else its FE81.
+struct chip_version_t
+{
+ int pre_bc7;
+ uint16 mask;
+ uint16 result;
+ uint8 sdio;
+};
+
+struct chip_device_desc_t
+{
+ struct chip_version_t chip_version;
+
+ // This is a text string that a human might find useful (BC02, BigFoot)
+ const char *friendly_name;
+ // This i swhat we show to customers
+ const char *marketing_name;
+
+ /* Initialisation values to write following a reset */
+ struct val_array_t init;
+
+ // Binary sequence for hard reset
+ struct reset_prog_t reset_prog;
+
+ // The register map
+ const struct chip_device_regs_t *regs;
+
+ // Some misc. info on the chip
+ struct
+ {
+ unsigned int has_flash : 1;
+ unsigned int has_ext_sram : 1;
+ unsigned int has_rom : 1;
+ unsigned int has_bt : 1;
+ unsigned int has_wlan : 1;
+ } bools;
+
+ // This table is used to remap register addresses depending on what
+ // host interface is used. On the BC7 and later chips there are
+ // multiple sets of memory window registers, on for each host
+ // interafce (SDIO / SPI). The correct one is needed.
+ struct map_array_t map;
+
+ // The offsets into the program address space of the different types of memory.
+ // The RAM offset is probably the most useful
+ struct
+ {
+ uint32 ram;
+ uint32 rom;
+ uint32 flash;
+ uint32 ext_sram;
+ } prog_offset;
+
+ // The offsets into the data address space of interesting things.
+ struct
+ {
+ uint16 ram;
+ // maybe add shared / page tables?
+ } data_offset;
+
+ // Information on the different windows
+ const struct window_info_t *windows[CHIP_HELPER_WINDOW_COUNT];
+};
+
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/download.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/download.c
new file mode 100644
index 0000000..6b08100
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/download.c
@@ -0,0 +1,1238 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: download.c
+ *
+ * PURPOSE:
+ * Routines for downloading firmware to UniFi.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "driver/unifiversion.h"
+#include "card.h"
+#include "xbv.h"
+
+#undef VERIFY_DOWNLOAD
+#undef IGNORE_PATCH_VERSION_MISMATCH
+
+static int check_firmware_version(card_t *card, const xbv1_t *fwinfo);
+static int set_entry_points(card_t *card, const symbol_t *slut_ptr, int slut_len);
+static uint32 find_slut_entry(uint16 id, const symbol_t *slut_ptr,
+ int slut_len);
+static int do_primary_download(card_t *card,
+ void *dlpriv,
+ xbv1_t *pfwinfo);
+static int do_secondary_download(card_t *card,
+ void *dlpriv,
+ xbv1_t *pfwinfo);
+static int do_patch_download(card_t *card,
+ void *dlpriv,
+ xbv1_t *pfwinfo,
+ uint32 boot_ctrl_addr);
+
+#ifdef VERIFY_DOWNLOAD
+static int verify_download(card_t *card,
+ unsigned long addr,
+ unsigned char *buf,
+ int len);
+#endif /* VERIFY_DOWNLOAD */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_dl_firmware
+ *
+ * Download the given firmware image to the UniFi.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * iread Pointer to a function to read parts of the firmware
+ * XBV file.
+ * dlpriv A context pointer from the calling function to be
+ * passed when calling iread().
+ * secondary If zero, indicates that the this is a primary
+ * download to bare metal, i.e. CMD53 may not be used.
+ * If non-zero, this indicates that a primary loader has
+ * already been loaded and we can use the faster CMD53
+ * to transfer download data.
+ *
+ * Returns:
+ * 0 on success,
+ * -ENOMEM memory allocation failed
+ * -EINVAL error in XBV file
+ * -EIO SDIO error
+ *
+ * Notes:
+ * Stops and resets the chip, does the download and runs the new
+ * firmware.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_dl_firmware(card_t *card, void *dlpriv, int secondary)
+{
+ xbv1_t *fwinfo;
+ symbol_t slut[32];
+ int num_slut_entries;
+ int r;
+
+ func_enter();
+
+ fwinfo = unifi_malloc(card->ospriv, sizeof(xbv1_t));
+ if (fwinfo == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate memory for firmware\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * Scan the firmware file to find the TLVs we are interested in.
+ * These are:
+ * - check we support the file format version in VERF
+ * - SLTP Symbol Lookup Table Pointer
+ * - FWDL firmware download segments
+ * - FWOV firmware overlay segment
+ * - VMEQ Register probe tests to verify matching h/w
+ */
+ r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
+ if (r || fwinfo->mode != xbv_firmware) {
+ unifi_free(card->ospriv, fwinfo);
+ return -EINVAL;
+ }
+
+ /* Save the info on the overlay for later. */
+ memcpy(&card->fwov, &fwinfo->fwov, sizeof(struct FWOV));
+
+ /*
+ * Read the SLUT from the f/w image.
+ * This can only be done once the f/w image has been parsed so we
+ * can find the SLUT address in the download data.
+ */
+ num_slut_entries = xbv1_read_slut(card, unifi_fw_read, dlpriv, fwinfo,
+ slut, sizeof(slut)/sizeof(slut[0]));
+ if (num_slut_entries <= 0) {
+ unifi_free(card->ospriv, fwinfo);
+ return -EINVAL;
+ }
+
+ /*
+ * A secondary download is done before stopping the XAPs
+ */
+ if (secondary) {
+ r = check_firmware_version(card, fwinfo);
+ if (r) {
+ if (r > 0) {
+ unifi_error(card->ospriv, "Wrong FW version for HW (HW=%04x)\n",
+ card->chip_version);
+ } else {
+ unifi_error(card->ospriv, "Error checking FW / HW version (HW=%04x)\n",
+ card->chip_version);
+ }
+ unifi_free(card->ospriv, fwinfo);
+ return r;
+ }
+ r = do_secondary_download(card, dlpriv, fwinfo);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to download image using secondary loader\n");
+ unifi_free(card->ospriv, fwinfo);
+ return r;
+ }
+ }
+
+
+ /* Stop the UniFis on-board processors */
+ r = card_stop_processor(card, UNIFI_PROC_BOTH);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to stop UniFi processors\n");
+ unifi_free(card->ospriv, fwinfo);
+ return r;
+ }
+
+ /*
+ * The XAPs must be stopped before doing a primary download.
+ */
+ if (!secondary) {
+ r = check_firmware_version(card, fwinfo);
+ if (r) {
+ if (r > 0) {
+ unifi_error(card->ospriv, "Wrong FW version for HW (HW=%04x)\n",
+ card->chip_version);
+ } else {
+ unifi_error(card->ospriv, "Error checking FW / HW version (HW=%04x)\n",
+ card->chip_version);
+ }
+ unifi_free(card->ospriv, fwinfo);
+ return r;
+ }
+ r = do_primary_download(card, dlpriv, fwinfo);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to copy image to UniFi memory\n");
+ unifi_free(card->ospriv, fwinfo);
+ return r;
+ }
+ }
+
+
+#if 0
+ /* read */
+ {
+ uint16 u;
+
+ r = unifi_read16(card, fwinfo.slut_addr, &u);
+ if (r) {
+ unifi_error(card->ospriv, "Failed read test loc\n");
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG2, "slut_addr 0x%lX = 0x%X\n", fwinfo.slut_addr, u);
+ }
+#endif
+
+ /* We don't need the fwinfo any more. */
+ unifi_free(card->ospriv, fwinfo);
+
+ /* Set the ResetVector registers to the entry point address */
+ r = set_entry_points(card, slut, num_slut_entries);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to set UniFi reset vectors\n");
+ return r;
+ }
+
+
+ /*
+ * Clear the SHARED_MAILBOX1 register, so the init code can see when
+ * the firmware sets it to 1.
+ */
+ r = unifi_write_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, 0);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to zero SHARED_MAILBOX1.\n");
+ return r;
+ }
+
+ /* Start both XAPs */
+ r = card_start_processor(card, UNIFI_PROC_BOTH);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to start UniFi processors\n");
+ return r;
+ }
+
+ func_exit();
+ return r;
+
+} /* unifi_dl_firmware() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_dl_patch
+ *
+ * Load the given patch set into UniFi.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * dlpriv The os specific handle to the firmware file.
+ * boot_ctrl The address of the boot loader control structure.
+ *
+ * Returns:
+ * 0 on success,
+ * -ENOMEM memory allocation failed
+ * -EINVAL error in XBV file
+ * -EIO SDIO error
+ *
+ * Notes:
+ * This ends up telling UniFi to restart.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_dl_patch(card_t *card, void *dlpriv, unsigned long boot_ctrl)
+{
+ xbv1_t *fwinfo;
+ int r;
+
+ func_enter();
+
+ unifi_info(card->ospriv, "unifi_dl_patch %p %08x\n", dlpriv, boot_ctrl);
+
+ fwinfo = unifi_malloc(card->ospriv, sizeof(xbv1_t));
+ if (fwinfo == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate memory for patches\n");
+ func_exit();
+ return -ENOMEM;
+ }
+
+ /*
+ * Scan the firmware file to find the TLVs we are interested in.
+ * These are:
+ * - check we support the file format version in VERF
+ * - FWID The build ID of the ROM that we can patch
+ * - PTDL patch download segments
+ */
+ r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
+ if (r || fwinfo->mode != xbv_patch) {
+ unifi_free(card->ospriv, fwinfo);
+ unifi_error(card->ospriv, "Failed to read in patch file\n");
+ func_exit();
+ return -EINVAL;
+ }
+
+ /*
+ * We have to check the build id read from the SLUT against that
+ * for the patch file. They have to match exactly.
+ * "card->build_id" == XBV1.PTCH.FWID
+ */
+ if (card->build_id != fwinfo->build_id) {
+ unifi_error(card->ospriv, "Wrong patch file for chip (chip = %lu, file = %lu)\n",
+ card->build_id, fwinfo->build_id);
+ unifi_free(card->ospriv, fwinfo);
+#ifndef IGNORE_PATCH_VERSION_MISMATCH
+ func_exit();
+ return -EINVAL;
+#else
+ fwinfo = NULL;
+ dlpriv = NULL;
+ return 0;
+#endif
+ }
+
+ r = do_patch_download(card, dlpriv, fwinfo, boot_ctrl);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to patch image\n");
+ }
+
+ unifi_free(card->ospriv, fwinfo);
+
+ func_exit();
+ return r;
+} /* unifi_dl_patch() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * check_firmware_version
+ *
+ * Process the entries in the XBV file that verify compatibility with
+ * the chip by checking various registers.
+ * The VMEQ and VAND sections of the XBV file allow arbitrary chip
+ * registers to be checked.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * fwinfo Pointer to a fwinfo struct describing the f/w
+ * XBV file.
+ *
+ * Returns:
+ * 0 if the verify opertaion succeeded AND the chip is compatible.
+ * 1 if the verify opertaion succeeded AND the chip is not compatible.
+ * -1 if a register read failed
+ * ---------------------------------------------------------------------------
+ */
+static int
+check_firmware_version(card_t *card, const xbv1_t *fwinfo)
+{
+ unsigned int i, j;
+ int r;
+ uint16 v;
+ const struct VAND *vand;
+ const struct VMEQ *vmeq;
+
+ for (j = 0; j < fwinfo->vers.num_vand; j++)
+ {
+ vand = fwinfo->vand + j;
+
+ for (i = 0, vmeq = fwinfo->vmeq + vand->first;
+ i < vand->count;
+ i++, vmeq++)
+ {
+ r = unifi_read16(card, vmeq->addr, &v);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read reg %05lx\n", vmeq->addr);
+ return r;
+ }
+ if ((v & vmeq->mask) != vmeq->value)
+ {
+ unifi_trace(card->ospriv, UDBG1, "Version reg mismatch addr:%05lx val:%04x\n",
+ vmeq->addr, v);
+ break;
+ }
+ }
+ /* If all tests passed, we match the condition */
+ if (i == vand->count) {
+ return 0;
+ }
+ }
+
+ /* Not compatible */
+ return 1;
+} /* check_firmware_version() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_entry_points
+ *
+ * Retrieve the entry point address for each XAP from the SLUT and
+ * use it to set the initial value of Program Counter.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * slut_ptr Pointer to the table in memory.
+ * slut_len Maximum length to search.
+ *
+ * Returns:
+ * 0 on success, non-zero error code on error
+ * ---------------------------------------------------------------------------
+ */
+static int set_an_entry_point(card_t *card, uint32 gp, int which)
+{
+ int r;
+ uint32 ep;
+
+ /*
+ * Take the offset part of the GenericPointer amd convert to a XAP
+ * 16-bit offset.
+ */
+ ep = UNIFI_GP_OFFSET(gp) / 2;
+ switch (UNIFI_GP_SPACE(gp))
+ {
+ case UNIFI_PHY_PMEM:
+ case UNIFI_MAC_PMEM:
+ ep += ChipHelper_PROGRAM_MEMORY_RAM_OFFSET(card->helper);
+ break;
+
+ case UNIFI_EXT_FLASH:
+ if (!ChipHelper_HasFlash(card->helper)) {
+ return -EINVAL;
+ }
+ ep += ChipHelper_PROGRAM_MEMORY_FLASH_OFFSET(card->helper);
+ break;
+
+ case UNIFI_EXT_SRAM:
+ if (!ChipHelper_HasExtSram(card->helper)) {
+ return -EINVAL;
+ }
+ ep += ChipHelper_PROGRAM_MEMORY_EXT_SRAM_OFFSET(card->helper);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Select the XAP */
+ r = unifi_set_proc_select(card, which);
+ if (r) {
+ return r;
+ }
+
+ /* Write PCL and PCH */
+ r = unifi_write_direct16(card, ChipHelper_XAP_PCL(card->helper) * 2, (uint16)(ep & 0xFFFF));
+ if (r) {
+ return r;
+ }
+ r = unifi_write_direct8(card, ChipHelper_XAP_PCH(card->helper) * 2, (uint8)((ep >> 16) & 0xFF));
+ if (r) {
+ return r;
+ }
+
+ return 0;
+}
+
+static int
+set_entry_points(card_t *card, const symbol_t *slut_ptr, int slut_len)
+{
+ uint32 ep;
+ int r;
+
+ /* Find SLT_Reset_Vector_PHY in SLUT */
+ ep = find_slut_entry(CSR_SLT_RESET_VECTOR_PHY, slut_ptr, slut_len);
+ if (ep == 0xFFFFFFFF) {
+ return -EINVAL;
+ }
+ r = set_an_entry_point(card, ep, UNIFI_PROC_PHY);
+ if (r) {
+ return r;
+ }
+
+ /* Find SLT_Reset_Vector_MAC in SLUT */
+ ep = find_slut_entry(CSR_SLT_RESET_VECTOR_MAC, slut_ptr, slut_len);
+ if (ep == 0xFFFFFFFF) {
+ return -EINVAL;
+ }
+ r = set_an_entry_point(card, ep, UNIFI_PROC_MAC);
+ if (r) {
+ return r;
+ }
+
+ return 0;
+} /* set_entry_points() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * find_slut_entry
+ *
+ * Search the Symbol Look Up Table for the given id,
+ * return the 32-bit symbol value if found.
+ *
+ * Arguments:
+ * id The SLUT id to search for.
+ * slut_ptr Pointer to the table in memory.
+ * slut_len Maximum length to search.
+ * This is a defensive measure to stop us walking off
+ * the end of valid memory if the table is junk.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static uint32
+find_slut_entry(uint16 id, const symbol_t *slut_ptr, int slut_len)
+{
+ int i;
+
+ for (i = 0; i < slut_len; i++) {
+ if (slut_ptr[i].id == id) {
+ return slut_ptr[i].obj;
+ }
+ }
+
+ return 0xFFFFFFFF;
+} /* find_slut_entry() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * do_primary_download
+ *
+ * This function downloads a firmware image to the UniFi by
+ * writing directly to memory, one byte at a time over SDIO.
+ * It is assumed that the XAP processors have been stopped.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * iread Pointer to a function to read parts of the firmware
+ * XBV file.
+ * dlpriv A context pointer from the calling function to be
+ * passed when calling iread().
+ * pfwinfo Pointer to a fwinfo struct describing the f/w
+ * XBV file.
+ *
+ * Returns:
+ * 0 on success,
+ * -ENOMEM memory allocation failed
+ * -EINVAL error in XBV file
+ * -EIO SDIO error
+ * ---------------------------------------------------------------------------
+ */
+static int
+do_primary_download(card_t *card,
+ void *dlpriv,
+ xbv1_t *pfwinfo)
+{
+ int i;
+ unsigned char *buf;
+ /* Work in chunks of up to 2K in size */
+ const int buf_size = 2*1024;
+
+ buf = unifi_malloc(card->ospriv, buf_size);
+ if (buf == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
+ return -ENOMEM;
+ }
+
+ /* Copy download data to UniFi memory */
+ for (i = 0; i < pfwinfo->num_fwdl; i++) {
+ unsigned long addr;
+ unsigned int offset;
+ int remaining;
+
+ unifi_trace(card->ospriv, UDBG3, "Downloading to 0x%lX for %d from offset %d\n",
+ pfwinfo->fwdl[i].dl_addr,
+ pfwinfo->fwdl[i].dl_size,
+ pfwinfo->fwdl[i].dl_offset);
+
+ addr = pfwinfo->fwdl[i].dl_addr;
+ offset = pfwinfo->fwdl[i].dl_offset;
+ remaining = pfwinfo->fwdl[i].dl_size;
+
+ while (remaining > 0) {
+ int r, len;
+ len = remaining;
+ if (len > buf_size) {
+ len = buf_size;
+ }
+ if (unifi_fw_read(card->ospriv, dlpriv, offset, buf, len) != len) {
+ unifi_free(card->ospriv, buf);
+ return -EINVAL;
+ }
+ r = unifi_writen(card, addr, buf, len);
+ if (r) {
+ unifi_free(card->ospriv, buf);
+ return r;
+ }
+
+ addr += len;
+ offset += len;
+ remaining -= len;
+ }
+ }
+
+ unifi_free(card->ospriv, buf);
+
+ return 0;
+} /* do_primary_download() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * safe_read_shared_location
+ *
+ * Read a shared memory location repeatedly until we get two readings
+ * the same.
+ *
+ * Arguments:
+ * card Pointer to card context struct.
+ * unifi_addr UniFi shared-data-memory address to access.
+ * pdata Pointer to a byte variable for the value read.
+ *
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ * ---------------------------------------------------------------------------
+ */
+static int
+safe_read_shared_location(card_t *card, uint32 address, uint8 *pdata)
+{
+ int r;
+ unsigned int limit = 1000;
+ uint8 b, b2;
+
+ r = unifi_read8(card, address, &b);
+ if (r) {
+ return r;
+ }
+
+ while (limit--) {
+ r = unifi_read8(card, address, &b2);
+ if (r) {
+ return r;
+ }
+
+ /* When we have a stable value, return it */
+ if (b == b2) {
+ *pdata = b;
+ return 0;
+ }
+
+ b = b2;
+ }
+
+ return -EIO;
+} /* safe_read_shared_location() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_do_loader_op
+ *
+ * Send a loader / boot_loader command to the UniFi and wait for
+ * it to complete.
+ *
+ * Arguments:
+ * card Pointer to card context struct.
+ * op_addr The address of the loader operation control word.
+ * opcode The operation to perform.
+ *
+ * Returns:
+ * Negative value indicating error code:
+ * -EIO SDIO error
+ * -ETIMEDOUT SDIO/XAP timeout
+ * ---------------------------------------------------------------------------
+ */
+
+#define OPERATION_TIMEOUT_LOOPS (500)
+#define OPERATION_TIMEOUT_DELAY 200
+
+int
+unifi_do_loader_op(card_t *card, unsigned long op_addr, unsigned char opcode)
+{
+ int r;
+ int op_retries;
+
+ /* Set the Operation command byte to the opcode */
+ r = unifi_write8(card, op_addr, opcode);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to write loader copy command\n");
+ return r;
+ }
+
+ /* Wait for Operation command byte to be Idle */
+ /* Typically takes ~100us */
+ op_retries = 0;
+ r = 0;
+ while (1) {
+ unsigned char op;
+
+ /*
+ * Read the memory location until two successive reads give
+ * the same value.
+ * Then handle it.
+ */
+ r = safe_read_shared_location(card, op_addr, &op);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read loader status\n");
+ break;
+ }
+
+ if (op == UNIFI_LOADER_IDLE) {
+ /* Success */
+ break;
+ }
+
+ if (op != opcode) {
+ unifi_error(card->ospriv, "Error reported by loader: 0x%X\n", op);
+ r = -EIO;
+ break;
+ }
+
+ /* Allow 500us timeout */
+ if (++op_retries >= OPERATION_TIMEOUT_LOOPS) {
+ unifi_error(card->ospriv, "Timeout waiting for loader to ack transfer\n");
+ /* Stop XAPs to aid post-mortem */
+ r = card_stop_processor(card, UNIFI_PROC_BOTH);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to stop UniFi processors\n");
+ } else {
+ r = -ETIMEDOUT;
+ }
+ break;
+ }
+ unifi_delay_us(card->ospriv, OPERATION_TIMEOUT_DELAY);
+
+ } /* Loop exits with r != 0 on error */
+
+ return r;
+} /* unifi_do_loader_op() */
+
+/*
+ * ---------------------------------------------------------------------------
+ * send_fwdl_to_unifi
+ *
+ * Copy a memory segment from userland to the UniFi.
+ * This function reads data, 2K at a time, from userland and writes
+ * it to the UniFi.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * Number of bytes sent (Positive) or negative value indicating
+ * error code:
+ * -ENOMEM memory allocation failed
+ * -EINVAL error in XBV file
+ * -EIO SDIO error
+ * ---------------------------------------------------------------------------
+ */
+static int
+send_fwdl_to_unifi(card_t *card, void *dlpriv,
+ struct FWDL *fwdl, unsigned long handle, unsigned long op_addr, int can_round)
+{
+ unsigned long addr;
+ unsigned int offset;
+ unsigned char *buf;
+ int remaining;
+ int r;
+ /* Loader protocol can handle transfers up to 2K in size */
+ const int buf_size = 2*1024;
+ /* Allow for 6 byte SDIO loader block header */
+ const int maxlen = (buf_size) - 6;
+
+ buf = unifi_malloc(card->ospriv, buf_size);
+ if (buf == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
+ return -ENOMEM;
+ }
+
+ addr = fwdl->dl_addr;
+ offset = fwdl->dl_offset;
+ remaining = fwdl->dl_size;
+
+ r = 0;
+ while (remaining > 0) {
+ int data_len, write_len;
+
+ data_len = remaining;
+ if (data_len > maxlen) {
+ data_len = maxlen;
+ }
+ /* Make sure the copy does not cross an 8K boundary */
+ if (((addr + data_len) & ~0x1FFF) != (addr & ~0x1FFF)) {
+ data_len = ((addr & ~0x1FFF) + 0x2000) - addr;
+ }
+
+ if (unifi_fw_read(card->ospriv, dlpriv, offset, buf+6, data_len) != data_len) {
+ unifi_error(card->ospriv, "Failed to read from file\n");
+ break;
+ }
+
+
+ /* Prepend the SDIO loader block header */
+ buf[0] = data_len & 0xFF;
+ buf[1] = (data_len >> 8) & 0xFF;
+ buf[2] = (unsigned char)(addr & 0xFF);
+ buf[3] = (unsigned char)((addr >> 8) & 0xFF);
+ buf[4] = (unsigned char)((addr >> 16) & 0xFF);
+ buf[5] = (unsigned char)((addr >> 24) & 0xFF);
+ write_len = data_len + 6;
+#ifdef UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE
+ if (can_round) {
+ write_len = (data_len + 6 + (card->sdio_io_block_size - 1)) &
+ ~(card->sdio_io_block_size - 1);
+ /* Zero out the rest of the buffer (This isn't needed, but
+ * it makes debugging things later much easier). */
+ memset(buf + data_len + 6, 0, write_len - (data_len + 6));
+ }
+#endif
+ r = unifi_bulk_rw_noretry(card, handle, buf, write_len, UNIFI_SDIO_WRITE);
+ if (r) {
+ unifi_error(card->ospriv, "CMD53 failed writing %d bytes to handle %ld\n",
+ data_len+6, handle);
+ break;
+ }
+
+ /*
+ * Can chage the order of things to overlap read from file
+ * with copy to unifi
+ */
+ r = unifi_do_loader_op(card, op_addr, UNIFI_LOADER_COPY);
+ if (r) {
+ break;
+ }
+
+#ifdef VERIFY_DOWNLOAD
+ verify_download(card, addr, buf+6, data_len);
+#endif /* VERIFY_DOWNLOAD */
+
+ addr += data_len;
+ offset += data_len;
+ remaining -= data_len;
+ }
+
+ unifi_free(card->ospriv, buf);
+
+ if (r && (r != -ENODEV)) {
+ unifi_error(card->ospriv, "Failed to copy block to UniFi after %u bytes of %u\n",
+ (fwdl->dl_size - remaining), fwdl->dl_size);
+ }
+
+ return r;
+} /* send_fwdl_to_unifi() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * send_ptdl_to_unifi
+ *
+ * Copy a patch block from userland to the UniFi.
+ * This function reads data, 2K at a time, from userland and writes
+ * it to the UniFi.
+ *
+ * Arguments:
+ * card A pointer to the card structure
+ * dlpriv The os specific handle for the firmware file
+ * ptdl A pointer ot the PTDL block
+ * handle The buffer handle to use for the xfer
+ * op_addr The address of the loader operation control word
+ *
+ * Returns:
+ * Number of bytes sent (Positive) or negative value indicating
+ * error code:
+ * -ENOMEM memory allocation failed
+ * -EINVAL error in XBV file
+ * -EIO SDIO error
+ * ---------------------------------------------------------------------------
+ */
+static int
+send_ptdl_to_unifi(card_t *card, void *dlpriv,
+ const struct PTDL *ptdl, unsigned long handle,
+ unsigned long op_addr)
+{
+ unsigned int offset;
+ unsigned char *buf;
+ unsigned int data_len, write_len;
+ int r;
+ const unsigned int buf_size = 2*1024;
+
+ offset = ptdl->dl_offset;
+ data_len = ptdl->dl_size;
+
+ if (data_len > buf_size) {
+ unifi_error(card->ospriv, "PTDL block is too large (%u)\n",
+ ptdl->dl_size);
+ return -EINVAL;
+ }
+
+ buf = unifi_malloc(card->ospriv, buf_size);
+ if (buf == NULL) {
+ unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
+ return -ENOMEM;
+ }
+
+ r = 0;
+
+ if (unifi_fw_read(card->ospriv, dlpriv, offset, buf, data_len) != data_len) {
+ unifi_error(card->ospriv, "Failed to read from file\n");
+ } else {
+
+ /* We can always round these if the host wants to */
+#ifdef UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE
+ write_len = (data_len + (card->sdio_io_block_size - 1)) &
+ ~(card->sdio_io_block_size - 1);
+
+ /* Zero out the rest of the buffer (This isn't needed, but it
+ * makes debugging things later much easier). */
+ memset(buf + data_len, 0, write_len - data_len);
+#else
+ write_len = data_len;
+#endif
+
+ r = unifi_bulk_rw_noretry(card, handle, buf, write_len, UNIFI_SDIO_WRITE);
+ if (r) {
+ unifi_error(card->ospriv, "CMD53 failed writing %d bytes to handle %ld\n",
+ data_len, handle);
+ } else {
+
+ /*
+ * Can change the order of things to overlap read from file
+ * with copy to unifi
+ */
+ r = unifi_do_loader_op(card, op_addr, UNIFI_BOOT_LOADER_PATCH);
+ }
+ }
+
+ unifi_free(card->ospriv, buf);
+
+ if (r && (r != -ENODEV)) {
+ unifi_error(card->ospriv, "Failed to copy block of %u bytes to UniFi\n",
+ ptdl->dl_size);
+ }
+
+ return r;
+} /* send_ptdl_to_unifi() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * do_secondary_download
+ *
+ * This function downloads a firmware image to the UniFi using the
+ * SDIO Loader protocol, supported by the secondary loader that is
+ * assumed to have been downloaded and started previously.
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * iread Pointer to a function to read parts of the firmware
+ * XBV file.
+ * dlpriv A context pointer from the calling function to be
+ * passed when calling iread().
+ * pfwinfo Pointer to a fwinfo struct describing the f/w
+ * XBV file.
+ *
+ * Returns:
+ * 0 on success, or an error code
+ * ---------------------------------------------------------------------------
+ */
+static int
+do_secondary_download(card_t *card,
+ void *dlpriv,
+ xbv1_t *pfwinfo)
+{
+ unsigned long slut_address, loader_ctrl_addr;
+ unsigned int total_bytes = 0;
+ uint16 finger_print;
+ int i, r;
+ uint16 loader_version;
+ uint16 handle;
+
+ r = card_wait_for_firmware_to_start(card, &slut_address);
+ if (r == -ENODEV) return r;
+ if (r) {
+ func_exit();
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG4, "Stage 2 download: SLUT addr 0x%lX\n", slut_address);
+
+ /*
+ * Check the SLUT fingerprint.
+ * The slut_address is a generic pointer so we must use unifi_read16().
+ */
+ unifi_trace(card->ospriv, UDBG4, "Stage 2 download: Looking for SLUT finger print\n");
+ finger_print = 0;
+ r = unifi_read16(card, slut_address, &finger_print);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Stage 2 download: Failed to read SLUT finger print\n");
+ func_exit();
+ return r;
+ }
+
+ if (finger_print != SLUT_FINGERPRINT) {
+ unifi_error(card->ospriv, "Stage 2 download: Failed to find Symbol lookup table fingerprint\n");
+ func_exit();
+ return -EINVAL;
+ }
+
+ /* Symbol table starts imedately after the fingerprint */
+ slut_address += 2;
+ loader_ctrl_addr = 0;
+ while (!loader_ctrl_addr) {
+ uint16 id;
+
+ r = unifi_read16(card, slut_address, &id);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Stage 2 download: Failed to read SLT address\n");
+ func_exit();
+ return r;
+ }
+ slut_address += 2;
+
+ if (id == CSR_SLT_END) {
+ break;
+ }
+
+ if (id == CSR_SLT_SDIO_LOADER_CONTROL) {
+ r = unifi_read32(card, slut_address, &loader_ctrl_addr);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Stage 2 download: Failed to read SLT_SDIO_LOADER_CONTROL value\n");
+ func_exit();
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG3,
+ "Stage 2 download: SDIO loader control struct @ 0x%08lX\n",
+ loader_ctrl_addr);
+ }
+ slut_address += 4;
+ }
+
+ /*
+ * Read info from the SDIO Loader Control Data Structure
+ */
+ /* Check the loader version */
+ r = unifi_read16(card, loader_ctrl_addr, &loader_version);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Stage 2 download: Failed to read loader version\n");
+ func_exit();
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG2, "Stage 2 download: SDIO loader version 0x%04X\n", loader_version);
+ switch (loader_version) {
+ case 0x0000:
+ case 0x0001:
+ /* These are the same, but with version 1 we can round up the
+ * length of data transfered (so we only need one CMD53, not
+ * two). */
+ break;
+
+ default:
+ unifi_error(card->ospriv, "Secondary loader version (0x%04X) is not supported by this driver\n",
+ loader_version);
+ return -EINVAL;
+ }
+
+ /* Retrieve the handle to use with CMD53 */
+ r = unifi_read16(card, loader_ctrl_addr+4, &handle);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Stage 2 download: Failed to read loader handle\n");
+ func_exit();
+ return r;
+ }
+
+ /* Set the mask of LEDs to flash */
+ if (card->loader_led_mask) {
+ r = unifi_write16(card, loader_ctrl_addr+2, (uint16)card->loader_led_mask);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Stage 2 download: Failed to write LED mask\n");
+ func_exit();
+ return r;
+ }
+ }
+
+ /* Copy download data to UniFi memory */
+ for (i = 0; i < pfwinfo->num_fwdl; i++)
+ {
+ unifi_trace(card->ospriv, UDBG3, "Stage 2 download: Downloading to 0x%lX for %d from offset %d\n",
+ pfwinfo->fwdl[i].dl_addr,
+ pfwinfo->fwdl[i].dl_size,
+ pfwinfo->fwdl[i].dl_offset);
+ r = send_fwdl_to_unifi(card, dlpriv, &pfwinfo->fwdl[i],
+ handle, loader_ctrl_addr+6,
+ loader_version != 0x0000);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Secondary download failed after %u bytes\n",
+ total_bytes);
+ return r;
+ }
+ total_bytes += pfwinfo->fwdl[i].dl_size;
+ }
+
+ return 0;
+} /* do_secondary_download() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * do_patch_download
+ *
+ * This function downloads a set of patches to UniFi and then
+ * causes it to restart.
+ *
+ * Arguments:
+ * card Pointer to card struct.
+ * dlpriv A context pointer from the calling function to be
+ * used when reading the XBV file. This can be NULL
+ * in which case not patches are applied.
+ * pfwinfo Pointer to a fwinfo struct describing the f/w
+ * XBV file.
+ * boot_ctrl_addr The address of the boot loader control structure.
+ *
+ * Returns:
+ * 0 on success, or an error code
+ * -EINVAL for a bad laoader version number
+ * ---------------------------------------------------------------------------
+ */
+static int
+do_patch_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo, uint32 boot_ctrl_addr)
+{
+ int r, i;
+ uint16 loader_version;
+ uint16 handle;
+ unsigned int total_bytes;
+
+ /*
+ * Read info from the SDIO Loader Control Data Structure
+ */
+ /* Check the loader version */
+ r = unifi_read16(card, boot_ctrl_addr, &loader_version);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Patch download: Failed to read loader version\n");
+ return r;
+ }
+ unifi_trace(card->ospriv, UDBG2, "Patch download: boot loader version 0x%04X\n", loader_version);
+ switch (loader_version) {
+ case 0x0000:
+ break;
+
+ default:
+ unifi_error(card->ospriv, "Patch loader version (0x%04X) is not supported by this driver\n",
+ loader_version);
+ return -EINVAL;
+ }
+
+ /* Retrieve the handle to use with CMD53 */
+ r = unifi_read16(card, boot_ctrl_addr+4, &handle);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Patch download: Failed to read loader handle\n");
+ return r;
+ }
+
+ /* Set the mask of LEDs to flash */
+ if (card->loader_led_mask) {
+ r = unifi_write16(card, boot_ctrl_addr+2,
+ (uint16)card->loader_led_mask);
+ if (r < 0) {
+ unifi_error(card->ospriv, "Patch download: Failed to write LED mask\n");
+ return r;
+ }
+ }
+
+ total_bytes = 0;
+
+ /* Copy download data to UniFi memory */
+ for (i = 0; i < pfwinfo->num_ptdl; i++)
+ {
+ unifi_trace(card->ospriv, UDBG3, "Patch download: Downloading for %d from offset %d\n",
+ pfwinfo->ptdl[i].dl_size,
+ pfwinfo->ptdl[i].dl_offset);
+
+ r = send_ptdl_to_unifi(card, dlpriv, &pfwinfo->ptdl[i],
+ handle, boot_ctrl_addr+6);
+ if (r == -ENODEV) return r;
+ if (r) {
+ unifi_error(card->ospriv, "Patch failed after %u bytes\n",
+ total_bytes);
+ return r;
+ }
+ total_bytes += pfwinfo->ptdl[i].dl_size;
+ }
+
+ return 0;
+} /* do_patch_download() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * verify_download
+ *
+ * Function to verify a segment of the download by reading back
+ * memory locations.
+ * This is extremely slow!
+ *
+ * Arguments:
+ * card Pointer to card struct
+ * addr Starting memory address of segment.
+ * buf Pointer to download data that should be present in
+ * memory.
+ * len Number of bytes to check at this address.
+ *
+ * Returns:
+ * Number of errors, i.e. bytes that differ from expected.
+ * ---------------------------------------------------------------------------
+ */
+#ifdef VERIFY_DOWNLOAD
+static int
+verify_download(card_t *card, unsigned long addr, unsigned char *buf, int len)
+{
+ int a, r;
+ unsigned char b;
+ int errors = 0;
+
+ unifi_info(card->ospriv, "verifying download to 0x%lX for %d bytes (src ptr %p)...\n",
+ addr, len, buf);
+
+ for (a = 0; a < len; a++) {
+ r = unifi_read8(card, addr+a, &b);
+ if (r) {
+ unifi_error(card->ospriv, "Failed to read addr 0x%lX while verifying download\n",
+ addr+a);
+ return -1;
+ }
+ if (b != buf[a]) {
+ if (errors == 0) {
+ unifi_error(card->ospriv, "Verify failed @ 0x%08lX: expected %02X, read %02X\n",
+ addr+a, buf[a], b);
+ }
+ errors++;
+ }
+ }
+
+ if (errors) {
+ unifi_error(card->ospriv, "Verify of download to 0x%lX for %d bytes failed: %d errors\n",
+ addr, len, errors);
+ }
+
+ return errors;
+} /* verify_download() */
+#endif /* VERIFY_DOWNLOAD */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/packing.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/packing.c
new file mode 100644
index 0000000..4ab9552
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/packing.c
@@ -0,0 +1,6904 @@
+/* This is an autogenerated file from hip_pack_gen.pl */
+
+#include "driver/signals.h"
+#include "driver/unifi.h"
+#include "driver/conversions.h"
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * get_packed_struct_size
+ *
+ * Examine a buffer containing a UniFi signal in wire-format.
+ * The first two bytes contain the signal ID, decode the signal ID and
+ * return the size, in bytes, of the signal, not including any bulk
+ * data.
+ *
+ * Arguments:
+ * buf Pointer to buffer to decode.
+ *
+ * Returns:
+ * -EINVAL if the signal ID is not recognised, otherwise the
+ * number of bytes occupied by the signal in the buffer. This is useful
+ * for stepping past the signal to the object in the buffer.
+ * ---------------------------------------------------------------------------
+ */
+int
+get_packed_struct_size(const uint8 *buf)
+{
+ int size = 0;
+ int sig_id;
+
+ sig_id = UNPACK16(buf, 0);
+
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ switch (sig_id)
+ {
+ case CSR_MLME_AUTHENTICATE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELBA_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETPROTECTION_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SNIFFJOIN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_WORD16_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREPORT_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_CHANNELSWITCH_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELETEKEYS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_CANCEL_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_HL_SYNC_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MICHAELMICFAILURE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT64;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREQUEST_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_WDS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESET_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_START_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_AUTHENTICATE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_MREQUEST_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_START_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_MEASURE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_POWERMGT_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCHEDULE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_GET_NEXT_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTHENTICATE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELETEKEYS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_DELBA_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_HL_SYNC_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SET_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREPORT_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETKEYS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT16;
+ size += 32/8;
+ break;
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_HL_SYNC_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLSTEARDOWN_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_FT_JOIN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_POWERMGT_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TPCADAPT_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_LINKMEASURE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MEASURE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCHEDULE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETKEYS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_PING_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CONNECTED_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CHANNELSWITCH_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_NEXT_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_CHANNELSWITCH_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_CANCEL_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_DLSTEARDOWN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_EAPOL_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MA_UNITDATA_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TPCADAPT_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETPROTECTION_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SNIFFJOIN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREQUEST_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_DELBA_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_WDS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_REASSOCIATE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DS_STA_NOTIFY_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLSTEARDOWN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTHENTICATE_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_VSPECIFIC_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_SCHEDULE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESET_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_WDS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_MREPORT_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_WDS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ break;
+ case CSR_MLME_ADDBA_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_JOIN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_STAKEYESTABLISHED_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_ADDTS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT32;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_EAPOL_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT32;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_LINKMEASURE_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CHANNELSWITCH_RESPONSE_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_STRING_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_FT_JOIN_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_JOIN_REQUEST_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT64;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_SET_CONFIRM_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_INDICATION_ID:
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += 48/8;
+ size += 48/8;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ size += SIZEOF_UINT16;
+ break;
+ default:
+ size = -EINVAL;
+ }
+ return size;
+} /* get_packed_struct_size() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_unpack_signal
+ *
+ * Unpack a wire-format signal into a host-native structure.
+ * This function handles any necessary conversions for endianness and
+ * places no restrictions on packing or alignment for the structure
+ * definition.
+ *
+ * Arguments:
+ * ptr Signal buffer to unpack.
+ * sig Pointer to destination structure to populate.
+ *
+ * Returns:
+ * 0 on success,
+ * -EINVAL if the ID of signal was not recognised.
+ * ---------------------------------------------------------------------------
+ */
+int
+read_unpack_signal(const uint8 *ptr, CSR_SIGNAL *sig)
+{
+ int index = 0;
+
+ sig->SignalPrimitiveHeader.SignalId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+
+ sig->SignalPrimitiveHeader.ReceiverProcessId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+
+ sig->SignalPrimitiveHeader.SenderProcessId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+
+ switch (sig->SignalPrimitiveHeader.SignalId)
+ {
+ case CSR_MLME_AUTHENTICATE_REQUEST_ID:
+ sig->u.MlmeAuthenticateRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAuthenticateRequest.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAuthenticateRequest.AuthenticationType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateRequest.AuthenticationFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
+ sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanConfirm.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELBA_REQUEST_ID:
+ sig->u.MlmeDelbaRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDelbaRequest.PeerQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDelbaRequest.Direction = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaRequest.Tid = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaRequest.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETPROTECTION_CONFIRM_ID:
+ sig->u.MlmeSetprotectionConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SNIFFJOIN_CONFIRM_ID:
+ sig->u.MlmeSniffjoinConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinConfirm.Resultcode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_REQUEST_ID:
+ sig->u.MlmeDlsRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDlsRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDlsRequest.DlsTimeoutValue = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsRequest.DlsResponseTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_REQUEST_ID:
+ sig->u.MlmeDeauthenticateRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDeauthenticateRequest.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDeauthenticateRequest.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_WORD16_INDICATION_ID:
+ sig->u.DebugWord16Indication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[8] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[9] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[10] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[11] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[12] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[13] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[14] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugWord16Indication.DebugWords[15] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_RESPONSE_ID:
+ sig->u.MlmeReassociateResponse.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateResponse.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeReassociateResponse.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeReassociateResponse.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateResponse.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateResponse.AssociationId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateResponse.RcpiRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateResponse.RsniRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREPORT_CONFIRM_ID:
+ sig->u.MlmeMreportConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_INDICATION_ID:
+ sig->u.MlmeRemoteRequestIndication.ContentOfFtActionFrame.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestIndication.ContentOfFtActionFrame.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeRemoteRequestIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_CHANNELSWITCH_REQUEST_ID:
+ sig->u.MlmeChannelswitchRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchRequest.Mode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchRequest.ChannelNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchRequest.SecondaryChannelOffset = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchRequest.ChannelSwitchCount = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_REQUEST_ID:
+ sig->u.MlmeScanRequest.ChannelList.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanRequest.ChannelList.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanRequest.Ifindex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanRequest.BssType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeScanRequest.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeScanRequest.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeScanRequest.ScanType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanRequest.ProbeDelay = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ sig->u.MlmeScanRequest.MinChannelTime = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanRequest.MaxChannelTime = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELETEKEYS_CONFIRM_ID:
+ sig->u.MlmeDeletekeysConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_CANCEL_REQUEST_ID:
+ sig->u.MaUnitdataCancelRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataCancelRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataCancelRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataCancelRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataCancelRequest.HostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_HL_SYNC_REQUEST_ID:
+ sig->u.MlmeHlSyncRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeHlSyncRequest.GroupAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID:
+ sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MICHAELMICFAILURE_INDICATION_ID:
+ sig->u.MlmeMichaelmicfailureIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMichaelmicfailureIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMichaelmicfailureIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMichaelmicfailureIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMichaelmicfailureIndication.Count = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeMichaelmicfailureIndication.Address.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeMichaelmicfailureIndication.KeyType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMichaelmicfailureIndication.KeyId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMichaelmicfailureIndication.Tsc = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID:
+ sig->u.MlmeAutonomousScanResultsRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsRequest.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
+ sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetRequest.TriggeredId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREQUEST_CONFIRM_ID:
+ sig->u.MlmeMrequestConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_WDS_CONFIRM_ID:
+ sig->u.MlmeDelWdsConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelWdsConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelWdsConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelWdsConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelWdsConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESET_REQUEST_ID:
+ sig->u.MlmeResetRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResetRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResetRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResetRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeResetRequest.StaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeResetRequest.SetDefaultMib = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_START_CONFIRM_ID:
+ sig->u.MlmeStartConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeStartConfirm.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
+ sig->u.MlmeScanCancelRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanCancelRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanCancelRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanCancelRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_INDICATION_ID:
+ sig->u.MlmeAssociateIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAssociateIndication.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAssociateIndication.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateIndication.ListenInterval = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateIndication.RcpiRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateIndication.RsniRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID:
+ sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsConfirm.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_REQUEST_ID:
+ sig->u.MlmeResourceRequestRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeResourceRequestRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_AUTHENTICATE_CONFIRM_ID:
+ sig->u.MlmeAuthenticateConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAuthenticateConfirm.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAuthenticateConfirm.AuthenticationType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_RESPONSE_ID:
+ sig->u.MlmeAddtsResponse.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsResponse.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsResponse.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsResponse.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddtsResponse.NonapQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_MREQUEST_INDICATION_ID:
+ sig->u.MlmeMrequestIndication.MeasurementRequestSet.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestIndication.MeasurementRequestSet.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeMrequestIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeMrequestIndication.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestIndication.NumberOfRepetitions = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestIndication.MeasurementCategory = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
+ sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanConfirm.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_START_REQUEST_ID:
+ sig->u.MlmeStartRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.Ifindex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.BeaconPeriod = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.Channel = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.ProbeDelay = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ sig->u.MlmeStartRequest.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStartRequest.BluetoothAmp = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_RESPONSE_ID:
+ sig->u.MlmeAssociateResponse.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateResponse.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAssociateResponse.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAssociateResponse.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateResponse.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateResponse.AssociationId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateResponse.RcpiRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateResponse.RsniRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
+ sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanRequest.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_INDICATION_ID:
+ sig->u.MlmeAddtsIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsIndication.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddtsIndication.NonapQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST_ID:
+ sig->u.MlmeResourceRequestLocalRequest.ResourceDescriptors.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestLocalRequest.ResourceDescriptors.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestLocalRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestLocalRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeResourceRequestLocalRequest.MacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_MEASURE_CONFIRM_ID:
+ sig->u.MlmeMeasureConfirm.MeasurementReportSet.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureConfirm.MeasurementReportSet.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureConfirm.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_POWERMGT_CONFIRM_ID:
+ sig->u.MlmePowermgtConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_INDICATION_ID:
+ sig->u.MlmeResourceRequestIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeResourceRequestIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
+ sig->u.MlmeAddPeriodicConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicConfirm.PeriodicId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCHEDULE_REQUEST_ID:
+ sig->u.MlmeScheduleRequest.ScheduleElement.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleRequest.ScheduleElement.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeScheduleRequest.NonapQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_GET_NEXT_CONFIRM_ID:
+ sig->u.MlmeGetNextConfirm.MibAttributeValue.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextConfirm.MibAttributeValue.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextConfirm.Status = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextConfirm.ErrorIndex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTHENTICATE_INDICATION_ID:
+ sig->u.MlmeAuthenticateIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAuthenticateIndication.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAuthenticateIndication.AuthenticationType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_INDICATION_ID:
+ sig->u.MlmeNeighborrepreqIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeNeighborrepreqIndication.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeNeighborrepreqIndication.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELETEKEYS_REQUEST_ID:
+ sig->u.MlmeDeletekeysRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysRequest.KeyId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeletekeysRequest.KeyType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDeletekeysRequest.Address.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_DELBA_CONFIRM_ID:
+ sig->u.MlmeDelbaConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDelbaConfirm.PeerQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDelbaConfirm.Direction = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaConfirm.Tid = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_HL_SYNC_CONFIRM_ID:
+ sig->u.MlmeHlSyncConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeHlSyncConfirm.GroupAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeHlSyncConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
+ sig->u.MlmeAddAutonomousScanRequest.ChannelList.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.ChannelList.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.Ifindex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.ChannelStartingFactor = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.BssType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddAutonomousScanRequest.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAddAutonomousScanRequest.ScanType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.ProbeDelay = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ sig->u.MlmeAddAutonomousScanRequest.MinChannelTime = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddAutonomousScanRequest.MaxChannelTime = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_CONFIRM_ID:
+ sig->u.MlmeDisassociateConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SET_REQUEST_ID:
+ sig->u.MlmeSetRequest.MibAttributeValue.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetRequest.MibAttributeValue.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
+ sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelAutonomousScanConfirm.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREPORT_INDICATION_ID:
+ sig->u.MlmeMreportIndication.MeasurementReportSet.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportIndication.MeasurementReportSet.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeMreportIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeMreportIndication.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportIndication.MeasurementCategory = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM_ID:
+ sig->u.MlmeResourceRequestLocalConfirm.ResourceDescriptors.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestLocalConfirm.ResourceDescriptors.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestLocalConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestLocalConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeResourceRequestLocalConfirm.MacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeResourceRequestLocalConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
+ sig->u.MlmeDelPeriodicRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicRequest.PeriodicId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETKEYS_REQUEST_ID:
+ sig->u.MlmeSetkeysRequest.Key.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysRequest.Key.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysRequest.Length = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysRequest.KeyId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysRequest.KeyType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeSetkeysRequest.Address.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeSetkeysRequest.ReceiveSequenceCount = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeSetkeysRequest.AuthenticatorSupplicantOrInitiatorPeer = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(&sig->u.MlmeSetkeysRequest.CipherSuiteSelector, &ptr[index], 32/8);
+ index += 32/8;
+ break;
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+ sig->u.MaSniffdataIndication.Data.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.Data.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.Timestamp = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MaSniffdataIndication.Duration = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.Rate = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.AntennaId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.Rssi = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.Snr = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaSniffdataIndication.FrequencyOffset = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ sig->u.MaSniffdataIndication.ReceptionStatus = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_RESPONSE_ID:
+ sig->u.MlmePingResponse.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmePingResponse.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmePingResponse.TransactionId[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.TransactionId[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.TransactionId[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.TransactionId[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.TransactionId[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.TransactionId[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.TransactionId[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingResponse.TransactionId[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_HL_SYNC_INDICATION_ID:
+ sig->u.MlmeHlSyncIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeHlSyncIndication.GroupAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeHlSyncIndication.SourceAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeHlSyncIndication.SequenceNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_REQUEST_ID:
+ sig->u.MlmeAddbaRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddbaRequest.PeerQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAddbaRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.Tid = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.BlockAckPolicy = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.BufferSize = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.BlockAckTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.AddbaFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaRequest.BlockAckStartingSequenceControl = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLSTEARDOWN_INDICATION_ID:
+ sig->u.MlmeDlsteardownIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDlsteardownIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDlsteardownIndication.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_FT_JOIN_REQUEST_ID:
+ sig->u.MlmeFtJoinRequest.ScanInformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.ScanInformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.StaInformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.StaInformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.Ifindex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeFtJoinRequest.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeFtJoinRequest.BeaconPeriod = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.Timestamp = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeFtJoinRequest.LocalTime = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeFtJoinRequest.Channel = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.JoinFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinRequest.ProbeDelay = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_POWERMGT_REQUEST_ID:
+ sig->u.MlmePowermgtRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtRequest.PowerManagementMode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtRequest.WakeUp = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtRequest.ReceiveDtims = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePowermgtRequest.ListenInterval = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_REQUEST_ID:
+ sig->u.MlmeDisassociateRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDisassociateRequest.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDisassociateRequest.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TPCADAPT_CONFIRM_ID:
+ sig->u.MlmeTpcadaptConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.RequestRate = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.RequestTransmitPower = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.RequestLinkMargin = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.ReportRate = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.ReportTransmitPower = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptConfirm.ReportLinkMargin = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_LINKMEASURE_CONFIRM_ID:
+ sig->u.MlmeLinkmeasureConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.TransmitPower = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.LinkMargin = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.ReceiveAntennaId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.TransmitAntennaId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.RcpiRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.RsniRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.RcpiReport = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureConfirm.RsniReport = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID:
+ sig->u.MlmeProtectedframedroppedIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeProtectedframedroppedIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeProtectedframedroppedIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeProtectedframedroppedIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeProtectedframedroppedIndication.Address1.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeProtectedframedroppedIndication.Address2.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_INDICATION_ID:
+ sig->u.MlmeNeighborreprespIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespIndication.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespIndication.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MEASURE_REQUEST_ID:
+ sig->u.MlmeMeasureRequest.MeasurementRequestSet.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureRequest.MeasurementRequestSet.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMeasureRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_CONFIRM_ID:
+ sig->u.MlmeAssociateConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.AssociationId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.RcpiRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.RsniRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.RcpiResponse = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateConfirm.RsniResponse = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID:
+ sig->u.MlmeAutonomousScanIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.BssType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAutonomousScanIndication.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAutonomousScanIndication.BeaconPeriod = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.Timestamp = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeAutonomousScanIndication.LocalTime = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeAutonomousScanIndication.Channel = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.ChannelFrequency = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.Rssi = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.Snr = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.ReportedFrameInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.RcpiMeasurement = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanIndication.RsniMeasurement = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
+ sig->u.MlmeDelPeriodicConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelPeriodicConfirm.PeriodicId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCHEDULE_INDICATION_ID:
+ sig->u.MlmeScheduleIndication.ScheduleElement.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleIndication.ScheduleElement.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_REQUEST_ID:
+ sig->u.MlmeNeighborrepreqRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETKEYS_CONFIRM_ID:
+ sig->u.MlmeSetkeysConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetkeysConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_RESPONSE_ID:
+ sig->u.DsUnitdataResponse.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataResponse.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.DsUnitdataResponse.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.DsUnitdataResponse.Sa.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.DsUnitdataResponse.TransmissionStatus = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataResponse.RoutingInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataResponse.ProvidedPriority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataResponse.ProvidedServiceClass = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataResponse.ProvidedHostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_PING_REQUEST_ID:
+ sig->u.MlmePingRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmePingRequest.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmePingRequest.TransactionId[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.TransactionId[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.TransactionId[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.TransactionId[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.TransactionId[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.TransactionId[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.TransactionId[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingRequest.TransactionId[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_CONFIRM_ID:
+ sig->u.DebugGenericConfirm.DebugVariable.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugVariable.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericConfirm.DebugWords[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_RESPONSE_ID:
+ sig->u.MlmeAddbaResponse.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddbaResponse.PeerQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAddbaResponse.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.Tid = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.BlockAckPolicy = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.BufferSize = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaResponse.BlockAckTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CONNECTED_INDICATION_ID:
+ sig->u.MlmeConnectedIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeConnectedIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeConnectedIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeConnectedIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeConnectedIndication.ConnectionStatus = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeConnectedIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_REQUEST_ID:
+ sig->u.MlmeNeighborreprespRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeNeighborreprespRequest.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeNeighborreprespRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CHANNELSWITCH_CONFIRM_ID:
+ sig->u.MlmeChannelswitchConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
+ sig->u.MlmeTriggeredGetIndication.MibAttributeValue.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTriggeredGetIndication.MibAttributeValue.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTriggeredGetIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTriggeredGetIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTriggeredGetIndication.Status = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTriggeredGetIndication.ErrorIndex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTriggeredGetIndication.TriggeredId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_NEXT_REQUEST_ID:
+ sig->u.MlmeGetNextRequest.MibAttribute.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextRequest.MibAttribute.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetNextRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_CONFIRM_ID:
+ sig->u.MlmeAddtsConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsConfirm.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID:
+ sig->u.MlmeAutonomousScanResultsIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsIndication.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAutonomousScanResultsIndication.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAutonomousScanResultsIndication.Channel = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsIndication.ChannelFrequency = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsIndication.Rssi = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanResultsIndication.Snr = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_REQUEST_ID:
+ sig->u.DebugGenericRequest.DebugVariable.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugVariable.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericRequest.DebugWords[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID:
+ sig->u.MlmeSetUnitdataFilterRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterRequest.UnitDataFilterMode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetUnitdataFilterRequest.ArpFilterAddress = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_CHANNELSWITCH_INDICATION_ID:
+ sig->u.MlmeChannelswitchIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeChannelswitchIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeChannelswitchIndication.Mode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchIndication.ChannelNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchIndication.SecondaryChannelOffset = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchIndication.ChannelSwitchCount = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_CANCEL_INDICATION_ID:
+ sig->u.DsUnitdataCancelIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataCancelIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataCancelIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataCancelIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataCancelIndication.HostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_DLSTEARDOWN_CONFIRM_ID:
+ sig->u.MlmeDlsteardownConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDlsteardownConfirm.PeerMacAddress1.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeDlsteardownConfirm.PeerMacAddress2.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDlsteardownConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_EAPOL_REQUEST_ID:
+ sig->u.MlmeEapolRequest.Data.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolRequest.Data.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeEapolRequest.Sa.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeEapolRequest.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeEapolRequest.Priority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolRequest.HostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MA_UNITDATA_CONFIRM_ID:
+ sig->u.MaUnitdataConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MaUnitdataConfirm.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MaUnitdataConfirm.Sa.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MaUnitdataConfirm.TransmissionStatus = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataConfirm.ProvidedPriority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataConfirm.ProvidedServiceClass = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataConfirm.ProvidedHostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ sig->u.MaUnitdataConfirm.Rate = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TPCADAPT_REQUEST_ID:
+ sig->u.MlmeTpcadaptRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeTpcadaptRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeTpcadaptRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptRequest.TransmitRate = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeTpcadaptRequest.TpcadaptFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_INDICATION_ID:
+ sig->u.DsUnitdataIndication.Data.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataIndication.Data.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.DsUnitdataIndication.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.DsUnitdataIndication.Sa.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.DsUnitdataIndication.RoutingInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataIndication.ReceptionStatus = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataIndication.Priority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataIndication.ServiceClass = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataIndication.HostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_CONFIRM_ID:
+ sig->u.MlmeRemoteRequestConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeRemoteRequestConfirm.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeRemoteRequestConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
+ sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetConfirm.TriggeredId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_RESPONSE_ID:
+ sig->u.MlmeResourceRequestResponse.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestResponse.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeResourceRequestResponse.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeResourceRequestResponse.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETPROTECTION_REQUEST_ID:
+ sig->u.MlmeSetprotectionRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeSetprotectionRequest.Address.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeSetprotectionRequest.ProtectType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetprotectionRequest.KeyType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SNIFFJOIN_REQUEST_ID:
+ sig->u.MlmeSniffjoinRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinRequest.Ifindex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinRequest.Channel = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSniffjoinRequest.ChannelStartingFactor = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_INDICATION_ID:
+ sig->u.MlmeReassociateIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeReassociateIndication.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeReassociateIndication.CurrentApAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeReassociateIndication.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateIndication.ListenInterval = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateIndication.RcpiRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateIndication.RsniRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_INDICATION_ID:
+ sig->u.DebugGenericIndication.DebugVariable.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugVariable.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugGenericIndication.DebugWords[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_INDICATION_ID:
+ sig->u.MlmeDeauthenticateIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDeauthenticateIndication.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDeauthenticateIndication.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREQUEST_REQUEST_ID:
+ sig->u.MlmeMrequestRequest.MeasurementRequestSet.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestRequest.MeasurementRequestSet.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeMrequestRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeMrequestRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestRequest.NumberOfRepetitions = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMrequestRequest.MeasurementCategory = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
+ sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelTriggeredGetConfirm.TriggeredId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_CONFIRM_ID:
+ sig->u.MlmeDeltsConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDeltsConfirm.NonapQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDeltsConfirm.TsInfo = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_DELBA_INDICATION_ID:
+ sig->u.MlmeDelbaIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDelbaIndication.PeerQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDelbaIndication.Direction = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaIndication.Tid = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelbaIndication.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_CONFIRM_ID:
+ sig->u.MlmeNeighborreprespConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborreprespConfirm.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_WDS_CONFIRM_ID:
+ sig->u.MlmeAddWdsConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddWdsConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddWdsConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddWdsConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddWdsConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_REQUEST_ID:
+ sig->u.MlmeAssociateRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAssociateRequest.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAssociateRequest.AssociateFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateRequest.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAssociateRequest.ListenInterval = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_REQUEST_ID:
+ sig->u.MlmeRemoteRequestRequest.ContentOfFtActionFrame.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestRequest.ContentOfFtActionFrame.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeRemoteRequestRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeRemoteRequestRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
+ sig->u.MlmeHlSyncCancelRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncCancelRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncCancelRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncCancelRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeHlSyncCancelRequest.GroupAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_REASSOCIATE_REQUEST_ID:
+ sig->u.MlmeReassociateRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeReassociateRequest.NewApAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeReassociateRequest.ReassociateFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateRequest.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateRequest.ListenInterval = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_INDICATION_ID:
+ sig->u.MlmeScanIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.Ifindex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.BssType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeScanIndication.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeScanIndication.BeaconPeriod = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.Timestamp = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeScanIndication.LocalTime = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeScanIndication.Channel = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.ChannelFrequency = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.Rssi = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.Snr = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.ReportedFrameInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.RcpiMeasurement = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanIndication.RsniMeasurement = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
+ sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanDoneIndication.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAutonomousScanDoneIndication.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_STA_NOTIFY_REQUEST_ID:
+ sig->u.DsStaNotifyRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsStaNotifyRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsStaNotifyRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsStaNotifyRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.DsStaNotifyRequest.StaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.DsStaNotifyRequest.UpdateType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_INDICATION_ID:
+ sig->u.MlmeDlsIndication.SupportedRates.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsIndication.SupportedRates.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDlsIndication.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDlsIndication.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsIndication.DlsTimeoutValue = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLSTEARDOWN_REQUEST_ID:
+ sig->u.MlmeDlsteardownRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsteardownRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDlsteardownRequest.PeerMacAddress1.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeDlsteardownRequest.PeerMacAddress2.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDlsteardownRequest.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
+ sig->u.MlmeAddTriggeredGetRequest.MibAttribute.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetRequest.MibAttribute.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddTriggeredGetRequest.TriggeredId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_CONFIRM_ID:
+ sig->u.MlmeGetConfirm.MibAttributeValue.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetConfirm.MibAttributeValue.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetConfirm.Status = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetConfirm.ErrorIndex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_CONFIRM_ID:
+ sig->u.MlmeDeauthenticateConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeauthenticateConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDeauthenticateConfirm.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDeauthenticateConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTHENTICATE_RESPONSE_ID:
+ sig->u.MlmeAuthenticateResponse.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateResponse.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAuthenticateResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAuthenticateResponse.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAuthenticateResponse.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_VSPECIFIC_REQUEST_ID:
+ sig->u.MlmeVspecificRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeVspecificRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeVspecificRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeVspecificRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeVspecificRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_SCHEDULE_CONFIRM_ID:
+ sig->u.MlmeScheduleConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScheduleConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_INDICATION_ID:
+ sig->u.MlmeDisassociateIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDisassociateIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDisassociateIndication.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDisassociateIndication.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESET_CONFIRM_ID:
+ sig->u.MlmeResetConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResetConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResetConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResetConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResetConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_CONFIRM_ID:
+ sig->u.MlmePingConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmePingConfirm.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmePingConfirm.TransactionId[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.TransactionId[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.TransactionId[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.TransactionId[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.TransactionId[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.TransactionId[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.TransactionId[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingConfirm.TransactionId[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_REQUEST_ID:
+ sig->u.DsUnitdataRequest.Data.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataRequest.Data.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.DsUnitdataRequest.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.DsUnitdataRequest.Sa.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.DsUnitdataRequest.RoutingInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataRequest.Priority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataRequest.ServiceClass = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DsUnitdataRequest.SourceType = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID:
+ sig->u.MlmeNeighborrepreqConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeNeighborrepreqConfirm.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_WDS_REQUEST_ID:
+ sig->u.MlmeAddWdsRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddWdsRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddWdsRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddWdsRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddWdsRequest.WdsApMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_MREPORT_REQUEST_ID:
+ sig->u.MlmeMreportRequest.MeasurementReportSet.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportRequest.MeasurementReportSet.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeMreportRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeMreportRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeMreportRequest.MeasurementCategory = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_WDS_REQUEST_ID:
+ sig->u.MlmeDelWdsRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelWdsRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelWdsRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDelWdsRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDelWdsRequest.WdsApMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_ADDBA_CONFIRM_ID:
+ sig->u.MlmeAddbaConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddbaConfirm.PeerQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAddbaConfirm.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.Tid = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.BlockAckPolicy = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.BufferSize = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaConfirm.BlockAckTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_JOIN_CONFIRM_ID:
+ sig->u.MlmeJoinConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_CONFIRM_ID:
+ sig->u.MlmeDlsConfirm.SupportedRates.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsConfirm.SupportedRates.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDlsConfirm.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDlsConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsConfirm.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDlsConfirm.DlsTimeoutValue = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_CONFIRM_ID:
+ sig->u.MlmeResourceRequestConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeResourceRequestConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeResourceRequestConfirm.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeResourceRequestConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_STAKEYESTABLISHED_INDICATION_ID:
+ sig->u.MlmeStakeyestablishedIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStakeyestablishedIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStakeyestablishedIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeStakeyestablishedIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeStakeyestablishedIndication.Address1.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MlmeStakeyestablishedIndication.Address2.x, &ptr[index], 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
+ sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanRequest.AutonomousScanId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePauseAutonomousScanRequest.Pause = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_CONFIRM_ID:
+ sig->u.MlmeReassociateConfirm.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.AssociationId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.RcpiRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.RsniRequest = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.RcpiResponse = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeReassociateConfirm.RsniResponse = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_REQUEST_ID:
+ sig->u.MlmeGetRequest.MibAttribute.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetRequest.MibAttribute.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeGetRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_REQUEST_ID:
+ sig->u.MaUnitdataRequest.Data.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataRequest.Data.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MaUnitdataRequest.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MaUnitdataRequest.Sa.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MaUnitdataRequest.RoutingInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataRequest.Priority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataRequest.ServiceClass = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataRequest.HostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_ADDTS_REQUEST_ID:
+ sig->u.MlmeAddtsRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddtsRequest.AddtsFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
+ sig->u.MlmeAddPeriodicRequest.DownlinkInformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicRequest.DownlinkInformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicRequest.UplinkInformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicRequest.UplinkInformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicRequest.PeriodicId = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicRequest.CoexistenceDirection = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicRequest.PeriodicSchedulingMode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddPeriodicRequest.WakeHost = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_INDICATION_ID:
+ sig->u.MlmePingIndication.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmePingIndication.PeerStaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmePingIndication.TransactionId[0] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.TransactionId[1] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.TransactionId[2] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.TransactionId[3] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.TransactionId[4] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.TransactionId[5] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.TransactionId[6] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmePingIndication.TransactionId[7] = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_INDICATION_ID:
+ sig->u.MlmeDeltsIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDeltsIndication.NonapQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDeltsIndication.TsInfo = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ sig->u.MlmeDeltsIndication.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_EAPOL_CONFIRM_ID:
+ sig->u.MlmeEapolConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolConfirm.ProvidedPriority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeEapolConfirm.ProvidedHostTag = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
+ sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeHlSyncCancelConfirm.GroupAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeHlSyncCancelConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_REQUEST_ID:
+ sig->u.MlmeDeltsRequest.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsRequest.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeDeltsRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeDeltsRequest.NonapQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeDeltsRequest.TsInfo = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ sig->u.MlmeDeltsRequest.ReasonCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_LINKMEASURE_REQUEST_ID:
+ sig->u.MlmeLinkmeasureRequest.InformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureRequest.InformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureRequest.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureRequest.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeLinkmeasureRequest.PeerMacAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeLinkmeasureRequest.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureRequest.TransmitPower = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeLinkmeasureRequest.MaxTransmitPower = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_CONFIRM_ID:
+ sig->u.MlmeScanConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeScanConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CHANNELSWITCH_RESPONSE_ID:
+ sig->u.MlmeChannelswitchResponse.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchResponse.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchResponse.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchResponse.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchResponse.Mode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchResponse.ChannelNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchResponse.SecondaryChannelOffset = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeChannelswitchResponse.ChannelSwitchCount = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_STRING_INDICATION_ID:
+ sig->u.DebugStringIndication.DebugMessage.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugStringIndication.DebugMessage.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugStringIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.DebugStringIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_FT_JOIN_CONFIRM_ID:
+ sig->u.MlmeFtJoinConfirm.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinConfirm.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeFtJoinConfirm.ResultCode = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_JOIN_REQUEST_ID:
+ sig->u.MlmeJoinRequest.ScanInformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.ScanInformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.StaInformationElements.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.StaInformationElements.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.Ifindex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeJoinRequest.Bssid.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeJoinRequest.BeaconPeriod = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.Timestamp = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeJoinRequest.LocalTime = UNPACK64(ptr, index);
+ index += SIZEOF_UINT64;
+ sig->u.MlmeJoinRequest.Channel = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.CapabilityInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.JoinFailureTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeJoinRequest.ProbeDelay = UNPACK32(ptr, index);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_SET_CONFIRM_ID:
+ sig->u.MlmeSetConfirm.MibAttributeValue.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetConfirm.MibAttributeValue.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetConfirm.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetConfirm.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetConfirm.Status = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeSetConfirm.ErrorIndex = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_INDICATION_ID:
+ sig->u.MlmeAddbaIndication.Dummydataref1.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaIndication.Dummydataref1.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MlmeAddbaIndication.PeerQstaAddress.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MlmeAddbaIndication.DialogToken = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaIndication.Tid = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaIndication.BlockAckPolicy = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaIndication.BufferSize = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MlmeAddbaIndication.BlockAckTimeout = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_INDICATION_ID:
+ sig->u.MaUnitdataIndication.Data.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.Data.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.Dummydataref2.SlotNumber = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.Dummydataref2.DataLength = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ memcpy(sig->u.MaUnitdataIndication.Da.x, &ptr[index], 48/8);
+ index += 48/8;
+ memcpy(sig->u.MaUnitdataIndication.Sa.x, &ptr[index], 48/8);
+ index += 48/8;
+ sig->u.MaUnitdataIndication.RoutingInformation = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.ReceptionStatus = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.Priority = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.ServiceClass = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.Rssi = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.Snr = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ sig->u.MaUnitdataIndication.Rate = UNPACK16(ptr, index);
+ index += SIZEOF_UINT16;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+} /* read_unpack_signal() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * write_pack
+ *
+ * Convert a signal structure, in host-native format, to the
+ * little-endian wire format specified in the UniFi Host Interface
+ * Protocol Specification.
+ *
+ * Arguments:
+ * sig Pointer to signal structure to pack.
+ * ptr Destination buffer to pack into.
+ * sig_len Returns the length of the packed signal, i.e. the
+ * number of bytes written to ptr.
+ *
+ * Returns:
+ * 0 on success,
+ * -EINVAL if the ID of signal was not recognised.
+ * ---------------------------------------------------------------------------
+ */
+int
+write_pack(const CSR_SIGNAL *sig, uint8 *ptr, unsigned int *sig_len)
+{
+ int index = 0;
+
+ LE_16(ptr+index, sig->SignalPrimitiveHeader.SignalId);
+ index += SIZEOF_UINT16;
+
+ LE_16(ptr+index, sig->SignalPrimitiveHeader.ReceiverProcessId);
+ index += SIZEOF_UINT16;
+
+ LE_16(ptr+index, sig->SignalPrimitiveHeader.SenderProcessId);
+ index += SIZEOF_UINT16;
+
+ switch (sig->SignalPrimitiveHeader.SignalId)
+ {
+ case CSR_MLME_AUTHENTICATE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAuthenticateRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAuthenticateRequest.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateRequest.AuthenticationType);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateRequest.AuthenticationFailureTimeout);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanConfirm.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELBA_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDelbaRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDelbaRequest.PeerQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDelbaRequest.Direction);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaRequest.Tid);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaRequest.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETPROTECTION_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeSetprotectionConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SNIFFJOIN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeSniffjoinConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinConfirm.Resultcode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDlsRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDlsRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDlsRequest.DlsTimeoutValue);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsRequest.DlsResponseTimeout);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDeauthenticateRequest.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateRequest.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_WORD16_INDICATION_ID:
+ LE_16(ptr+index, sig->u.DebugWord16Indication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[7]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[8]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[9]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[10]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[11]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[12]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[13]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[14]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugWord16Indication.DebugWords[15]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeReassociateResponse.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.AssociationId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.RcpiRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateResponse.RsniRequest);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREPORT_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeMreportConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestIndication.ContentOfFtActionFrame.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestIndication.ContentOfFtActionFrame.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeRemoteRequestIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_CHANNELSWITCH_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.Mode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.ChannelNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.SecondaryChannelOffset);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchRequest.ChannelSwitchCount);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeScanRequest.ChannelList.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.ChannelList.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.Ifindex);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.BssType);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeScanRequest.Da.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeScanRequest.Bssid.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.ScanType);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeScanRequest.ProbeDelay);
+ index += SIZEOF_UINT32;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.MinChannelTime);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanRequest.MaxChannelTime);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELETEKEYS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDeletekeysConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_CANCEL_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MaUnitdataCancelRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataCancelRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataCancelRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataCancelRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MaUnitdataCancelRequest.HostTag);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_HL_SYNC_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeHlSyncRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeHlSyncRequest.GroupAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MICHAELMICFAILURE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeMichaelmicfailureIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMichaelmicfailureIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMichaelmicfailureIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMichaelmicfailureIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMichaelmicfailureIndication.Count);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeMichaelmicfailureIndication.Address.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeMichaelmicfailureIndication.KeyType);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMichaelmicfailureIndication.KeyId);
+ index += SIZEOF_UINT16;
+ LE_64(ptr+index, sig->u.MlmeMichaelmicfailureIndication.Tsc);
+ index += SIZEOF_UINT64;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsRequest.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetRequest.TriggeredId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREQUEST_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeMrequestConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_WDS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDelWdsConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelWdsConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelWdsConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelWdsConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelWdsConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESET_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeResetRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResetRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResetRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResetRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeResetRequest.StaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeResetRequest.SetDefaultMib);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_START_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeStartConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeStartConfirm.Bssid.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeScanCancelRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanCancelRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanCancelRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanCancelRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAssociateIndication.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.ListenInterval);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.RcpiRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateIndication.RsniRequest);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsConfirm.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeResourceRequestRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeResourceRequestRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_AUTHENTICATE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAuthenticateConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAuthenticateConfirm.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateConfirm.AuthenticationType);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmeAddtsResponse.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsResponse.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsResponse.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsResponse.DialogToken);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddtsResponse.NonapQstaAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_MREQUEST_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeMrequestIndication.MeasurementRequestSet.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestIndication.MeasurementRequestSet.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeMrequestIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeMrequestIndication.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestIndication.NumberOfRepetitions);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestIndication.MeasurementCategory);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanConfirm.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_START_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeStartRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.Ifindex);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.BeaconPeriod);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.Channel);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeStartRequest.ProbeDelay);
+ index += SIZEOF_UINT32;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStartRequest.BluetoothAmp);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAssociateResponse.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.AssociationId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.RcpiRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateResponse.RsniRequest);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanRequest.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeAddtsIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsIndication.DialogToken);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddtsIndication.NonapQstaAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalRequest.ResourceDescriptors.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalRequest.ResourceDescriptors.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeResourceRequestLocalRequest.MacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_MEASURE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeMeasureConfirm.MeasurementReportSet.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureConfirm.MeasurementReportSet.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureConfirm.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_POWERMGT_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmePowermgtConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeResourceRequestIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeResourceRequestIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicConfirm.PeriodicId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCHEDULE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeScheduleRequest.ScheduleElement.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleRequest.ScheduleElement.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeScheduleRequest.NonapQstaAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_GET_NEXT_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeGetNextConfirm.MibAttributeValue.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextConfirm.MibAttributeValue.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextConfirm.Status);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextConfirm.ErrorIndex);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTHENTICATE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeAuthenticateIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAuthenticateIndication.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateIndication.AuthenticationType);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeNeighborrepreqIndication.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqIndication.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELETEKEYS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDeletekeysRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysRequest.KeyId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeletekeysRequest.KeyType);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDeletekeysRequest.Address.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_DELBA_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDelbaConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDelbaConfirm.PeerQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDelbaConfirm.Direction);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaConfirm.Tid);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_HL_SYNC_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeHlSyncConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeHlSyncConfirm.GroupAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeHlSyncConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.ChannelList.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.ChannelList.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.Ifindex);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.ChannelStartingFactor);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.BssType);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddAutonomousScanRequest.Bssid.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.ScanType);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeAddAutonomousScanRequest.ProbeDelay);
+ index += SIZEOF_UINT32;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.MinChannelTime);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddAutonomousScanRequest.MaxChannelTime);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDisassociateConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SET_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeSetRequest.MibAttributeValue.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetRequest.MibAttributeValue.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelAutonomousScanConfirm.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREPORT_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeMreportIndication.MeasurementReportSet.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportIndication.MeasurementReportSet.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeMreportIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeMreportIndication.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportIndication.MeasurementCategory);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalConfirm.ResourceDescriptors.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalConfirm.ResourceDescriptors.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeResourceRequestLocalConfirm.MacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestLocalConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicRequest.PeriodicId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETKEYS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.Key.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.Key.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.Length);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.KeyId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.KeyType);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeSetkeysRequest.Address.x, 48/8);
+ index += 48/8;
+ LE_64(ptr+index, sig->u.MlmeSetkeysRequest.ReceiveSequenceCount);
+ index += SIZEOF_UINT64;
+ LE_16(ptr+index, sig->u.MlmeSetkeysRequest.AuthenticatorSupplicantOrInitiatorPeer);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, &sig->u.MlmeSetkeysRequest.CipherSuiteSelector, 32/8);
+ index += 32/8;
+ break;
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Data.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Data.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_64(ptr+index, sig->u.MaSniffdataIndication.Timestamp);
+ index += SIZEOF_UINT64;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Duration);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Rate);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.AntennaId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Rssi);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.Snr);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MaSniffdataIndication.FrequencyOffset);
+ index += SIZEOF_UINT32;
+ LE_16(ptr+index, sig->u.MaSniffdataIndication.ReceptionStatus);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmePingResponse.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmePingResponse.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingResponse.TransactionId[7]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_HL_SYNC_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeHlSyncIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeHlSyncIndication.GroupAddress.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeHlSyncIndication.SourceAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeHlSyncIndication.SequenceNumber);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddbaRequest.PeerQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.Tid);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.BlockAckPolicy);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.BufferSize);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.BlockAckTimeout);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.AddbaFailureTimeout);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaRequest.BlockAckStartingSequenceControl);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLSTEARDOWN_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeDlsteardownIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDlsteardownIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownIndication.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_FT_JOIN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.ScanInformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.ScanInformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.StaInformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.StaInformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.Ifindex);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeFtJoinRequest.Bssid.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.BeaconPeriod);
+ index += SIZEOF_UINT16;
+ LE_64(ptr+index, sig->u.MlmeFtJoinRequest.Timestamp);
+ index += SIZEOF_UINT64;
+ LE_64(ptr+index, sig->u.MlmeFtJoinRequest.LocalTime);
+ index += SIZEOF_UINT64;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.Channel);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinRequest.JoinFailureTimeout);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeFtJoinRequest.ProbeDelay);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_POWERMGT_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.PowerManagementMode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.WakeUp);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.ReceiveDtims);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePowermgtRequest.ListenInterval);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDisassociateRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDisassociateRequest.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDisassociateRequest.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TPCADAPT_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.RequestRate);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.RequestTransmitPower);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.RequestLinkMargin);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.ReportRate);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.ReportTransmitPower);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptConfirm.ReportLinkMargin);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_LINKMEASURE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.TransmitPower);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.LinkMargin);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.ReceiveAntennaId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.TransmitAntennaId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.RcpiRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.RsniRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.RcpiReport);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureConfirm.RsniReport);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeProtectedframedroppedIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeProtectedframedroppedIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeProtectedframedroppedIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeProtectedframedroppedIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeProtectedframedroppedIndication.Address1.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeProtectedframedroppedIndication.Address2.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespIndication.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespIndication.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MEASURE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeMeasureRequest.MeasurementRequestSet.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureRequest.MeasurementRequestSet.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMeasureRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.AssociationId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.RcpiRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.RsniRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.RcpiResponse);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateConfirm.RsniResponse);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.BssType);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAutonomousScanIndication.Bssid.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.BeaconPeriod);
+ index += SIZEOF_UINT16;
+ LE_64(ptr+index, sig->u.MlmeAutonomousScanIndication.Timestamp);
+ index += SIZEOF_UINT64;
+ LE_64(ptr+index, sig->u.MlmeAutonomousScanIndication.LocalTime);
+ index += SIZEOF_UINT64;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.Channel);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.ChannelFrequency);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.Rssi);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.Snr);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.ReportedFrameInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.RcpiMeasurement);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanIndication.RsniMeasurement);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelPeriodicConfirm.PeriodicId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCHEDULE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeScheduleIndication.ScheduleElement.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleIndication.ScheduleElement.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETKEYS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeSetkeysConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetkeysConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.DsUnitdataResponse.Da.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.DsUnitdataResponse.Sa.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.TransmissionStatus);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.RoutingInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.ProvidedPriority);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataResponse.ProvidedServiceClass);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.DsUnitdataResponse.ProvidedHostTag);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_PING_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmePingRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmePingRequest.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingRequest.TransactionId[7]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugVariable.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugVariable.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericConfirm.DebugWords[7]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddbaResponse.PeerQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.Tid);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.BlockAckPolicy);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.BufferSize);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaResponse.BlockAckTimeout);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CONNECTED_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeConnectedIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeConnectedIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeConnectedIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeConnectedIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeConnectedIndication.ConnectionStatus);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeConnectedIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeNeighborreprespRequest.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CHANNELSWITCH_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeChannelswitchConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeTriggeredGetIndication.MibAttributeValue.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTriggeredGetIndication.MibAttributeValue.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTriggeredGetIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTriggeredGetIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTriggeredGetIndication.Status);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTriggeredGetIndication.ErrorIndex);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTriggeredGetIndication.TriggeredId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_NEXT_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeGetNextRequest.MibAttribute.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextRequest.MibAttribute.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetNextRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDTS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAddtsConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsConfirm.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Bssid.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Channel);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.ChannelFrequency);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Rssi);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanResultsIndication.Snr);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_REQUEST_ID:
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugVariable.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugVariable.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericRequest.DebugWords[7]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetUnitdataFilterRequest.UnitDataFilterMode);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeSetUnitdataFilterRequest.ArpFilterAddress);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_CHANNELSWITCH_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeChannelswitchIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.Mode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.ChannelNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.SecondaryChannelOffset);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchIndication.ChannelSwitchCount);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_CANCEL_INDICATION_ID:
+ LE_16(ptr+index, sig->u.DsUnitdataCancelIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataCancelIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataCancelIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataCancelIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.DsUnitdataCancelIndication.HostTag);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_DLSTEARDOWN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDlsteardownConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDlsteardownConfirm.PeerMacAddress1.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeDlsteardownConfirm.PeerMacAddress2.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_EAPOL_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeEapolRequest.Data.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolRequest.Data.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeEapolRequest.Sa.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeEapolRequest.Da.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeEapolRequest.Priority);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeEapolRequest.HostTag);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MA_UNITDATA_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MaUnitdataConfirm.Da.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MaUnitdataConfirm.Sa.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.TransmissionStatus);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.ProvidedPriority);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.ProvidedServiceClass);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MaUnitdataConfirm.ProvidedHostTag);
+ index += SIZEOF_UINT32;
+ LE_16(ptr+index, sig->u.MaUnitdataConfirm.Rate);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_TPCADAPT_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeTpcadaptRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeTpcadaptRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptRequest.TransmitRate);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeTpcadaptRequest.TpcadaptFailureTimeout);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_INDICATION_ID:
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.Data.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.Data.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.DsUnitdataIndication.Da.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.DsUnitdataIndication.Sa.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.RoutingInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.ReceptionStatus);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.Priority);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataIndication.ServiceClass);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.DsUnitdataIndication.HostTag);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeRemoteRequestConfirm.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetConfirm.TriggeredId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmeResourceRequestResponse.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestResponse.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeResourceRequestResponse.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestResponse.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SETPROTECTION_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeSetprotectionRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeSetprotectionRequest.Address.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionRequest.ProtectType);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetprotectionRequest.KeyType);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SNIFFJOIN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeSniffjoinRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinRequest.Ifindex);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinRequest.Channel);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSniffjoinRequest.ChannelStartingFactor);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeReassociateIndication.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeReassociateIndication.CurrentApAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.ListenInterval);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.RcpiRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateIndication.RsniRequest);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_GENERIC_INDICATION_ID:
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugVariable.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugVariable.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugGenericIndication.DebugWords[7]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDeauthenticateIndication.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateIndication.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_MREQUEST_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeMrequestRequest.MeasurementRequestSet.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestRequest.MeasurementRequestSet.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeMrequestRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeMrequestRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestRequest.NumberOfRepetitions);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMrequestRequest.MeasurementCategory);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelTriggeredGetConfirm.TriggeredId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDeltsConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDeltsConfirm.NonapQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_32(ptr+index, sig->u.MlmeDeltsConfirm.TsInfo);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_DELBA_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeDelbaIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDelbaIndication.PeerQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDelbaIndication.Direction);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaIndication.Tid);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelbaIndication.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborreprespConfirm.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_WDS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAddWdsConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddWdsConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddWdsConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddWdsConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddWdsConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ASSOCIATE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAssociateRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAssociateRequest.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAssociateRequest.AssociateFailureTimeout);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateRequest.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAssociateRequest.ListenInterval);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestRequest.ContentOfFtActionFrame.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestRequest.ContentOfFtActionFrame.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeRemoteRequestRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeRemoteRequestRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeHlSyncCancelRequest.GroupAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_REASSOCIATE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeReassociateRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeReassociateRequest.NewApAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeReassociateRequest.ReassociateFailureTimeout);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateRequest.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateRequest.ListenInterval);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeScanIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.Ifindex);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.BssType);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeScanIndication.Bssid.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.BeaconPeriod);
+ index += SIZEOF_UINT16;
+ LE_64(ptr+index, sig->u.MlmeScanIndication.Timestamp);
+ index += SIZEOF_UINT64;
+ LE_64(ptr+index, sig->u.MlmeScanIndication.LocalTime);
+ index += SIZEOF_UINT64;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.Channel);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.ChannelFrequency);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.Rssi);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.Snr);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.ReportedFrameInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.RcpiMeasurement);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanIndication.RsniMeasurement);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanDoneIndication.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAutonomousScanDoneIndication.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_STA_NOTIFY_REQUEST_ID:
+ LE_16(ptr+index, sig->u.DsStaNotifyRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsStaNotifyRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsStaNotifyRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsStaNotifyRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.DsStaNotifyRequest.StaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.DsStaNotifyRequest.UpdateType);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeDlsIndication.SupportedRates.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsIndication.SupportedRates.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDlsIndication.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDlsIndication.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsIndication.DlsTimeoutValue);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLSTEARDOWN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDlsteardownRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDlsteardownRequest.PeerMacAddress1.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeDlsteardownRequest.PeerMacAddress2.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDlsteardownRequest.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetRequest.MibAttribute.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetRequest.MibAttribute.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddTriggeredGetRequest.TriggeredId);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeGetConfirm.MibAttributeValue.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetConfirm.MibAttributeValue.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetConfirm.Status);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetConfirm.ErrorIndex);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDeauthenticateConfirm.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDeauthenticateConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_AUTHENTICATE_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmeAuthenticateResponse.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateResponse.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAuthenticateResponse.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAuthenticateResponse.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_VSPECIFIC_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeVspecificRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeVspecificRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeVspecificRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeVspecificRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeVspecificRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_SCHEDULE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeScheduleConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScheduleConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DISASSOCIATE_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeDisassociateIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDisassociateIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDisassociateIndication.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDisassociateIndication.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESET_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeResetConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResetConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResetConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResetConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResetConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmePingConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmePingConfirm.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingConfirm.TransactionId[7]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DS_UNITDATA_REQUEST_ID:
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.Data.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.Data.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.DsUnitdataRequest.Da.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.DsUnitdataRequest.Sa.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.RoutingInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.Priority);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.ServiceClass);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DsUnitdataRequest.SourceType);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeNeighborrepreqConfirm.DialogToken);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_WDS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAddWdsRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddWdsRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddWdsRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddWdsRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddWdsRequest.WdsApMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_MREPORT_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeMreportRequest.MeasurementReportSet.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportRequest.MeasurementReportSet.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeMreportRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeMreportRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeMreportRequest.MeasurementCategory);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DEL_WDS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDelWdsRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelWdsRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelWdsRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDelWdsRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDelWdsRequest.WdsApMacAddress.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_ADDBA_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddbaConfirm.PeerQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.Tid);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.BlockAckPolicy);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.BufferSize);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaConfirm.BlockAckTimeout);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_JOIN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeJoinConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DLS_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeDlsConfirm.SupportedRates.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsConfirm.SupportedRates.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDlsConfirm.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeDlsConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsConfirm.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDlsConfirm.DlsTimeoutValue);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeResourceRequestConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeResourceRequestConfirm.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeResourceRequestConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_STAKEYESTABLISHED_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeStakeyestablishedIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStakeyestablishedIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStakeyestablishedIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeStakeyestablishedIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeStakeyestablishedIndication.Address1.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MlmeStakeyestablishedIndication.Address2.x, 48/8);
+ index += 48/8;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanRequest.AutonomousScanId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePauseAutonomousScanRequest.Pause);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_REASSOCIATE_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.AssociationId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.RcpiRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.RsniRequest);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.RcpiResponse);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeReassociateConfirm.RsniResponse);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_GET_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeGetRequest.MibAttribute.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetRequest.MibAttribute.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeGetRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MaUnitdataRequest.Data.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataRequest.Data.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MaUnitdataRequest.Da.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MaUnitdataRequest.Sa.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MaUnitdataRequest.RoutingInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataRequest.Priority);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataRequest.ServiceClass);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MaUnitdataRequest.HostTag);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_ADDTS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAddtsRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddtsRequest.AddtsFailureTimeout);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.DownlinkInformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.DownlinkInformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.UplinkInformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.UplinkInformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.PeriodicId);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.CoexistenceDirection);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.PeriodicSchedulingMode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddPeriodicRequest.WakeHost);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_PING_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmePingIndication.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmePingIndication.PeerStaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[0]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[1]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[2]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[3]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[4]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[5]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[6]);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmePingIndication.TransactionId[7]);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeDeltsIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDeltsIndication.NonapQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_32(ptr+index, sig->u.MlmeDeltsIndication.TsInfo);
+ index += SIZEOF_UINT32;
+ LE_16(ptr+index, sig->u.MlmeDeltsIndication.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_EAPOL_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeEapolConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeEapolConfirm.ProvidedPriority);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeEapolConfirm.ProvidedHostTag);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeHlSyncCancelConfirm.GroupAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeHlSyncCancelConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_DELTS_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeDeltsRequest.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsRequest.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeDeltsRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeDeltsRequest.NonapQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_32(ptr+index, sig->u.MlmeDeltsRequest.TsInfo);
+ index += SIZEOF_UINT32;
+ LE_16(ptr+index, sig->u.MlmeDeltsRequest.ReasonCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_LINKMEASURE_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureRequest.InformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureRequest.InformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureRequest.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureRequest.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeLinkmeasureRequest.PeerMacAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureRequest.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureRequest.TransmitPower);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeLinkmeasureRequest.MaxTransmitPower);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_SCAN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeScanConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeScanConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_CHANNELSWITCH_RESPONSE_ID:
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.Mode);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.ChannelNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.SecondaryChannelOffset);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeChannelswitchResponse.ChannelSwitchCount);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_DEBUG_STRING_INDICATION_ID:
+ LE_16(ptr+index, sig->u.DebugStringIndication.DebugMessage.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugStringIndication.DebugMessage.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugStringIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.DebugStringIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_FT_JOIN_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeFtJoinConfirm.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinConfirm.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeFtJoinConfirm.ResultCode);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_JOIN_REQUEST_ID:
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.ScanInformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.ScanInformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.StaInformationElements.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.StaInformationElements.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.Ifindex);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeJoinRequest.Bssid.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.BeaconPeriod);
+ index += SIZEOF_UINT16;
+ LE_64(ptr+index, sig->u.MlmeJoinRequest.Timestamp);
+ index += SIZEOF_UINT64;
+ LE_64(ptr+index, sig->u.MlmeJoinRequest.LocalTime);
+ index += SIZEOF_UINT64;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.Channel);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.CapabilityInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeJoinRequest.JoinFailureTimeout);
+ index += SIZEOF_UINT16;
+ LE_32(ptr+index, sig->u.MlmeJoinRequest.ProbeDelay);
+ index += SIZEOF_UINT32;
+ break;
+ case CSR_MLME_SET_CONFIRM_ID:
+ LE_16(ptr+index, sig->u.MlmeSetConfirm.MibAttributeValue.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetConfirm.MibAttributeValue.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetConfirm.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetConfirm.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetConfirm.Status);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeSetConfirm.ErrorIndex);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MLME_ADDBA_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.Dummydataref1.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.Dummydataref1.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MlmeAddbaIndication.PeerQstaAddress.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.DialogToken);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.Tid);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.BlockAckPolicy);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.BufferSize);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MlmeAddbaIndication.BlockAckTimeout);
+ index += SIZEOF_UINT16;
+ break;
+ case CSR_MA_UNITDATA_INDICATION_ID:
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Data.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Data.DataLength);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Dummydataref2.SlotNumber);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Dummydataref2.DataLength);
+ index += SIZEOF_UINT16;
+ memcpy(ptr+index, sig->u.MaUnitdataIndication.Da.x, 48/8);
+ index += 48/8;
+ memcpy(ptr+index, sig->u.MaUnitdataIndication.Sa.x, 48/8);
+ index += 48/8;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.RoutingInformation);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.ReceptionStatus);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Priority);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.ServiceClass);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Rssi);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Snr);
+ index += SIZEOF_UINT16;
+ LE_16(ptr+index, sig->u.MaUnitdataIndication.Rate);
+ index += SIZEOF_UINT16;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ *sig_len = index;
+
+ return 0;
+} /* write_pack() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/placeholder.txt b/unifi_hostsw_linux_147/unifi-linux/lib_hip/placeholder.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/placeholder.txt
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/send.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/send.c
new file mode 100644
index 0000000..f73d26b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/send.c
@@ -0,0 +1,325 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: send.c
+ *
+ * PURPOSE:
+ * Code for adding a signal request to the from-host queue.
+ * When the driver bottom-half is run, it will take requests from the
+ * queue and pass them to the UniFi.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include "driver/unifi.h"
+#include "driver/conversions.h"
+#include "driver/sigs.h"
+#include "card.h"
+
+static unsigned int
+unifi_frame_priority_to_queue(unsigned int priority)
+{
+ switch (priority) {
+ case CSR_QOS_UP0:
+ case CSR_QOS_UP3:
+ return 1;
+ case CSR_QOS_UP1:
+ case CSR_QOS_UP2:
+ return 0;
+ case CSR_QOS_UP4:
+ case CSR_QOS_UP5:
+ return 2;
+ case CSR_QOS_UP6:
+ case CSR_QOS_UP7:
+ return 3;
+ default:
+ return 1;
+ }
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * send_signal
+ *
+ * This function queues a signal for sending to UniFi. It first checks
+ * that there is space on the fh_signal_queue for another entry, then
+ * claims any bulk data slots required and copies data into them. Then
+ * increments the fh_signal_queue write count.
+ *
+ * The fh_signal_queue is later processed by the driver bottom half
+ * (in unifi_bh()).
+ *
+ * This function call unifi_pause_xmit() to pause the flow of data plane
+ * packets when:
+ * - the fh_signal_queue ring buffer is full
+ * - there are less than UNIFI_MAX_DATA_REFERENCES (2) bulk data
+ * slots available.
+ *
+ * Arguments:
+ * card Pointer to card context structure
+ * sigptr Pointer to the signal to write to UniFi.
+ * siglen Number of bytes pointer to by sigptr.
+ * bulkdata Array of pointers to an associated bulk data.
+ * sigq To which from-host queue to add the signal.
+ *
+ * Returns:
+ * 0 on success
+ * -EIO if there were insufficient data slots or no free signal queue entry
+ *
+ * Notes:
+ * Calls unifi_pause_xmit() when the last slots are used.
+ * ---------------------------------------------------------------------------
+ */
+static int
+send_signal(card_t *card, const unsigned char *sigptr, int siglen,
+ const bulk_data_param_t *bulkdata,
+ q_t *sigq, int run_bh)
+{
+ int i, data_slot_size;
+ card_signal_t *csptr;
+ int qe, r;
+ int debug_print = 0;
+
+ data_slot_size = CardGetDataSlotSize(card);
+
+ /* Check that the fh_data_queue has a free slot */
+ if (!q_slots_free(sigq)) {
+ unifi_error(card->ospriv, "send_signal: %s full\n", sigq->name);
+ return -ENOSPC;
+ }
+
+ /*
+ * Now add the signal to the From Host signal queue
+ */
+ /* Get next slot on queue */
+ qe = q_next_w_slot(sigq);
+ csptr = q_slot_data(sigq, qe);
+
+ /* Make up the card_signal struct */
+ csptr->signal_length = siglen;
+ memcpy((void*)csptr->sigbuf, (void*)sigptr, siglen);
+
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i) {
+ if ((bulkdata != NULL) && (bulkdata->d[i].data_length != 0)) {
+ int datalen = bulkdata->d[i].data_length;
+
+ /* Make sure data will fit in a bulk data slot */
+ if (bulkdata->d[i].os_data_ptr == NULL) {
+ unifi_error(card->ospriv, "send_signal - NULL bulkdata[%d]\n", i);
+ debug_print++;
+ csptr->bulkdata[i].data_length = 0;
+ } else {
+ if (datalen > data_slot_size) {
+ unifi_error(card->ospriv,
+ "send_signal - Invalid data length %u (@%p), "
+ "truncating\n",
+ datalen, bulkdata->d[i].os_data_ptr);
+ datalen = data_slot_size;
+ debug_print++;
+ }
+ /* Store the bulk data info in the soft queue. */
+ csptr->bulkdata[i].os_data_ptr = (unsigned char*)bulkdata->d[i].os_data_ptr;
+ csptr->bulkdata[i].os_net_buf_ptr = (unsigned char*)bulkdata->d[i].os_net_buf_ptr;
+ csptr->bulkdata[i].net_buf_length = bulkdata->d[i].net_buf_length;
+ csptr->bulkdata[i].data_length = datalen;
+ }
+ } else {
+ unifi_init_bulk_data(&csptr->bulkdata[i]);
+ }
+ }
+
+ if (debug_print) {
+ const unsigned char *sig = sigptr;
+
+ unifi_error(card->ospriv, "Signal(%d): %02x %02x %02x %02x %02x %02x %02x %02x"
+ " %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ siglen,
+ sig[0], sig[1], sig[2], sig[3],
+ sig[4], sig[5], sig[6], sig[7],
+ sig[8], sig[9], sig[10], sig[11],
+ sig[12], sig[13], sig[14], sig[15]);
+ unifi_error(card->ospriv, "Bulkdata pointer %p(%d), %p(%d)\n",
+ bulkdata != NULL ? bulkdata->d[0].os_data_ptr : NULL,
+ bulkdata != NULL ? bulkdata->d[0].data_length : 0,
+ bulkdata != NULL ? bulkdata->d[1].os_data_ptr : NULL,
+ bulkdata != NULL ? bulkdata->d[1].data_length : 0);
+ }
+
+ /* Advance the written count to say there is a new entry */
+ q_inc_w(sigq);
+
+ /*
+ * Set the flag to say reason for waking was a host request.
+ * Then ask the OS layer to run the unifi_bh.
+ */
+ if (run_bh == 1) {
+ card->bh_reason_host = 1;
+ r = unifi_run_bh(card->ospriv);
+ if (r) {
+ unifi_error(card->ospriv, "failed to run bh.\n");
+ card->bh_reason_host = 0;
+
+ /*
+ * The bulk data buffer will be freed by the caller.
+ * We need to invalidate the description of the bulk data in our
+ * soft queue, to prevent the core freeing the bulk data again later.
+ */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i) {
+ if (csptr->bulkdata[i].data_length != 0) {
+ csptr->bulkdata[i].os_data_ptr = csptr->bulkdata[i].os_net_buf_ptr = NULL;
+ csptr->bulkdata[i].net_buf_length = csptr->bulkdata[i].data_length = 0;
+ }
+ }
+ return r;
+ }
+ }
+
+ /*
+ * Have we used up all the fh signal list entries?
+ */
+ if (q_slots_free(sigq) == 0) {
+ /* We have filled the queue, so stop the upper layer */
+ card->paused = 1;
+ unifi_pause_xmit(card->ospriv);
+ }
+
+ func_exit();
+
+ return 0;
+} /* send_signal() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_send_signal
+ *
+ * Invokes send_signal() to queue a signal in the command or traffic queue
+ * If sigptr pointer is NULL, it pokes the bh to check if UniFi is responsive.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * sigptr Pointer to signal from card.
+ * siglen Size of the signal
+ * bulkdata Pointer to the bulk data of the signal
+ *
+ * Returns:
+ * 0 on success
+ * -1 if there were insufficient data slots or no free signal queue entry
+ *
+ * Notes:
+ * unifi_send_signal() is used to queue signals, created by the driver,
+ * to the device. Signals are constructed using the UniFi packed structures.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_send_signal(card_t *card, const unsigned char *sigptr, int siglen,
+ const bulk_data_param_t *bulkdata)
+{
+ q_t *sig_soft_q;
+ unsigned int signal_id;
+ int r;
+ int i;
+ int run_bh;
+
+ /* A NULL signal pointer is a request to check if UniFi is responsive */
+ if (sigptr == NULL) {
+ card->bh_reason_host = 1;
+ return unifi_run_bh(card->ospriv);
+ }
+
+ run_bh = 1;
+ signal_id = GET_SIGNAL_ID(sigptr);
+ /*
+ * If the signal is a CSR_MA_UNITDATA_REQUEST or a CSR_DS_UNITDATA_REQUEST,
+ * we send it using the traffic soft queue. Else we use the command soft queue.
+ */
+ if (signal_id == CSR_MA_UNITDATA_REQUEST_ID) {
+ unsigned int frame_priority;
+ unsigned int priority_q;
+
+ if (card->periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_ENABLED) {
+ run_bh = 0;
+ }
+
+ /* Map the frame priority to a traffic queue index. */
+ frame_priority = GET_PACKED_MA_UNIDATA_REQUEST_FRAME_PRIORITY(sigptr);
+ priority_q = unifi_frame_priority_to_queue(frame_priority);
+
+ sig_soft_q = &card->fh_traffic_queue[priority_q];
+ } else if (signal_id == CSR_DS_UNITDATA_REQUEST_ID) {
+ sig_soft_q = &card->fh_traffic_queue[0];
+ } else {
+ sig_soft_q = &card->fh_command_queue;
+ }
+
+ r = send_signal(card, sigptr, siglen, bulkdata, sig_soft_q, run_bh);
+ if (r && bulkdata) {
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i)
+ {
+ if (bulkdata->d[i].data_length != 0) {
+ unifi_net_data_free(card->ospriv, (bulk_data_desc_t*)(&bulkdata->d[i]));
+ }
+ }
+ }
+
+ return r;
+} /* unifi_send_signal() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_send_resources_available
+ *
+ * Examines whether there is available space to queue
+ * a signal in the command or traffic queue
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * sigptr Pointer to signal.
+ *
+ * Returns:
+ * 0 on success
+ * -ENOSPC if there was no free signal queue entry
+ *
+ * Notes:
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_send_resources_available(card_t *card, const unsigned char *sigptr)
+{
+ q_t *sig_soft_q;
+ unsigned int signal_id = GET_SIGNAL_ID(sigptr);
+
+ /*
+ * If the signal is a CSR_MA_UNITDATA_REQUEST or a CSR_DS_UNITDATA_REQUEST,
+ * we send it using the traffic soft queue. Else we use the command soft queue.
+ */
+ if (signal_id == CSR_MA_UNITDATA_REQUEST_ID) {
+ unsigned int frame_priority;
+ unsigned int priority_q;
+
+ /* Map the frame priority to a traffic queue index. */
+ frame_priority = GET_PACKED_MA_UNIDATA_REQUEST_FRAME_PRIORITY(sigptr);
+ priority_q = unifi_frame_priority_to_queue(frame_priority);
+
+ sig_soft_q = &card->fh_traffic_queue[priority_q];
+ } else if (signal_id == CSR_DS_UNITDATA_REQUEST_ID) {
+ sig_soft_q = &card->fh_traffic_queue[0];
+ } else {
+ sig_soft_q = &card->fh_command_queue;
+ }
+
+ /* Check that the fh_data_queue has a free slot */
+ if (!q_slots_free(sig_soft_q)) {
+ unifi_notice(card->ospriv, "unifi_send_resources_available: %s full\n",
+ sig_soft_q->name);
+ return -ENOSPC;
+ }
+
+ return 0;
+} /* unifi_send_resources_available() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/signals.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/signals.c
new file mode 100644
index 0000000..7a3d05d
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/signals.c
@@ -0,0 +1,1298 @@
+/* This is an autogenerated file from hip_dd_l_c_gen.pl */
+
+#include "driver/signals.h"
+
+/*
+ * unifi_os.h must provide a definition of the offsetof() macro
+ * unifi_os.h is included in unifi.h
+ * If you have an ISO C compiler, you can just #include <stddef.h>
+ */
+#include "driver/unifi.h"
+
+int SigGetSize(const CSR_SIGNAL* aSignal)
+{
+ switch(aSignal->SignalPrimitiveHeader.SignalId)
+ {
+ case CSR_MA_UNITDATA_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_UNITDATA_REQUEST);
+ case CSR_MA_UNITDATA_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_UNITDATA_CONFIRM);
+ case CSR_MA_UNITDATA_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_UNITDATA_INDICATION);
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_SNIFFDATA_INDICATION);
+ case CSR_MA_UNITDATA_CANCEL_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_UNITDATA_CANCEL_REQUEST);
+ case CSR_MLME_RESET_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESET_REQUEST);
+ case CSR_MLME_RESET_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESET_CONFIRM);
+ case CSR_MLME_GET_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_REQUEST);
+ case CSR_MLME_GET_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_CONFIRM);
+ case CSR_MLME_SET_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_REQUEST);
+ case CSR_MLME_SET_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_CONFIRM);
+ case CSR_MLME_GET_NEXT_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_NEXT_REQUEST);
+ case CSR_MLME_GET_NEXT_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_NEXT_CONFIRM);
+ case CSR_MLME_POWERMGT_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_POWERMGT_REQUEST);
+ case CSR_MLME_POWERMGT_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_POWERMGT_CONFIRM);
+ case CSR_MLME_SCAN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_REQUEST);
+ case CSR_MLME_SCAN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_CONFIRM);
+ case CSR_MLME_SCAN_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_INDICATION);
+ case CSR_MLME_JOIN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_JOIN_REQUEST);
+ case CSR_MLME_JOIN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_JOIN_CONFIRM);
+ case CSR_MLME_AUTHENTICATE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTHENTICATE_REQUEST);
+ case CSR_MLME_AUTHENTICATE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTHENTICATE_CONFIRM);
+ case CSR_MLME_AUTHENTICATE_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTHENTICATE_RESPONSE);
+ case CSR_MLME_AUTHENTICATE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTHENTICATE_INDICATION);
+ case CSR_MLME_DEAUTHENTICATE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEAUTHENTICATE_REQUEST);
+ case CSR_MLME_DEAUTHENTICATE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEAUTHENTICATE_CONFIRM);
+ case CSR_MLME_DEAUTHENTICATE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEAUTHENTICATE_INDICATION);
+ case CSR_MLME_ASSOCIATE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ASSOCIATE_REQUEST);
+ case CSR_MLME_ASSOCIATE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ASSOCIATE_CONFIRM);
+ case CSR_MLME_ASSOCIATE_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ASSOCIATE_RESPONSE);
+ case CSR_MLME_ASSOCIATE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ASSOCIATE_INDICATION);
+ case CSR_MLME_REASSOCIATE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_REASSOCIATE_REQUEST);
+ case CSR_MLME_REASSOCIATE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_REASSOCIATE_CONFIRM);
+ case CSR_MLME_REASSOCIATE_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_REASSOCIATE_RESPONSE);
+ case CSR_MLME_REASSOCIATE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_REASSOCIATE_INDICATION);
+ case CSR_MLME_DISASSOCIATE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DISASSOCIATE_REQUEST);
+ case CSR_MLME_DISASSOCIATE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DISASSOCIATE_CONFIRM);
+ case CSR_MLME_DISASSOCIATE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DISASSOCIATE_INDICATION);
+ case CSR_MLME_START_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_START_REQUEST);
+ case CSR_MLME_START_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_START_CONFIRM);
+ case CSR_MLME_ADDTS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDTS_REQUEST);
+ case CSR_MLME_ADDTS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDTS_CONFIRM);
+ case CSR_MLME_ADDTS_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDTS_RESPONSE);
+ case CSR_MLME_ADDTS_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDTS_INDICATION);
+ case CSR_MLME_DELTS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELTS_REQUEST);
+ case CSR_MLME_DELTS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELTS_CONFIRM);
+ case CSR_MLME_DELTS_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELTS_INDICATION);
+ case CSR_MLME_DLS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DLS_REQUEST);
+ case CSR_MLME_DLS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DLS_CONFIRM);
+ case CSR_MLME_DLS_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DLS_INDICATION);
+ case CSR_MLME_DLSTEARDOWN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DLSTEARDOWN_REQUEST);
+ case CSR_MLME_DLSTEARDOWN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DLSTEARDOWN_CONFIRM);
+ case CSR_MLME_DLSTEARDOWN_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DLSTEARDOWN_INDICATION);
+ case CSR_MLME_HL_SYNC_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_REQUEST);
+ case CSR_MLME_HL_SYNC_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CONFIRM);
+ case CSR_MLME_HL_SYNC_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_INDICATION);
+ case CSR_MLME_ADDBA_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDBA_REQUEST);
+ case CSR_MLME_ADDBA_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDBA_CONFIRM);
+ case CSR_MLME_ADDBA_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDBA_RESPONSE);
+ case CSR_MLME_ADDBA_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADDBA_INDICATION);
+ case CSR_MLME_DELBA_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELBA_REQUEST);
+ case CSR_MLME_DELBA_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELBA_CONFIRM);
+ case CSR_MLME_DELBA_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELBA_INDICATION);
+ case CSR_MLME_SCHEDULE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCHEDULE_REQUEST);
+ case CSR_MLME_SCHEDULE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCHEDULE_CONFIRM);
+ case CSR_MLME_SCHEDULE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCHEDULE_INDICATION);
+ case CSR_MLME_MREQUEST_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MREQUEST_REQUEST);
+ case CSR_MLME_MREQUEST_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MREQUEST_CONFIRM);
+ case CSR_MLME_MREQUEST_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MREQUEST_INDICATION);
+ case CSR_MLME_MEASURE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_REQUEST);
+ case CSR_MLME_MEASURE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_CONFIRM);
+ case CSR_MLME_MREPORT_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MREPORT_REQUEST);
+ case CSR_MLME_MREPORT_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MREPORT_CONFIRM);
+ case CSR_MLME_MREPORT_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MREPORT_INDICATION);
+ case CSR_MLME_CHANNELSWITCH_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CHANNELSWITCH_REQUEST);
+ case CSR_MLME_CHANNELSWITCH_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CHANNELSWITCH_CONFIRM);
+ case CSR_MLME_CHANNELSWITCH_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CHANNELSWITCH_RESPONSE);
+ case CSR_MLME_CHANNELSWITCH_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CHANNELSWITCH_INDICATION);
+ case CSR_MLME_TPCADAPT_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_TPCADAPT_REQUEST);
+ case CSR_MLME_TPCADAPT_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_TPCADAPT_CONFIRM);
+ case CSR_MLME_SETKEYS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETKEYS_REQUEST);
+ case CSR_MLME_SETKEYS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETKEYS_CONFIRM);
+ case CSR_MLME_DELETEKEYS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELETEKEYS_REQUEST);
+ case CSR_MLME_DELETEKEYS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELETEKEYS_CONFIRM);
+ case CSR_MLME_MICHAELMICFAILURE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MICHAELMICFAILURE_INDICATION);
+ case CSR_MLME_EAPOL_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_EAPOL_REQUEST);
+ case CSR_MLME_EAPOL_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_EAPOL_CONFIRM);
+ case CSR_MLME_STAKEYESTABLISHED_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STAKEYESTABLISHED_INDICATION);
+ case CSR_MLME_SETPROTECTION_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETPROTECTION_REQUEST);
+ case CSR_MLME_SETPROTECTION_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETPROTECTION_CONFIRM);
+ case CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION);
+ case CSR_MLME_SNIFFJOIN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SNIFFJOIN_REQUEST);
+ case CSR_MLME_SNIFFJOIN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SNIFFJOIN_CONFIRM);
+ case CSR_MLME_CONNECTED_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONNECTED_INDICATION);
+ case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_CANCEL_REQUEST);
+ case CSR_MLME_LINKMEASURE_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_LINKMEASURE_REQUEST);
+ case CSR_MLME_LINKMEASURE_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_LINKMEASURE_CONFIRM);
+ case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CANCEL_REQUEST);
+ case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CANCEL_CONFIRM);
+ case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_PERIODIC_REQUEST);
+ case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_PERIODIC_CONFIRM);
+ case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_PERIODIC_REQUEST);
+ case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_PERIODIC_CONFIRM);
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST);
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM);
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST);
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM);
+ case CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_INDICATION);
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST);
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM);
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION);
+ case CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_UNITDATA_FILTER_REQUEST);
+ case CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_UNITDATA_FILTER_CONFIRM);
+ case CSR_MLME_FT_JOIN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_FT_JOIN_REQUEST);
+ case CSR_MLME_FT_JOIN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_FT_JOIN_CONFIRM);
+ case CSR_MLME_RESOURCE_REQUEST_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESOURCE_REQUEST_REQUEST);
+ case CSR_MLME_RESOURCE_REQUEST_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESOURCE_REQUEST_CONFIRM);
+ case CSR_MLME_RESOURCE_REQUEST_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESOURCE_REQUEST_RESPONSE);
+ case CSR_MLME_RESOURCE_REQUEST_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESOURCE_REQUEST_INDICATION);
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST);
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM);
+ case CSR_MLME_REMOTE_REQUEST_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_REMOTE_REQUEST_REQUEST);
+ case CSR_MLME_REMOTE_REQUEST_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_REMOTE_REQUEST_CONFIRM);
+ case CSR_MLME_REMOTE_REQUEST_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_REMOTE_REQUEST_INDICATION);
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST);
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM);
+ case CSR_MLME_NEIGHBORREPREQ_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_NEIGHBORREPREQ_REQUEST);
+ case CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_NEIGHBORREPREQ_CONFIRM);
+ case CSR_MLME_NEIGHBORREPREQ_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_NEIGHBORREPREQ_INDICATION);
+ case CSR_MLME_NEIGHBORREPRESP_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_NEIGHBORREPRESP_REQUEST);
+ case CSR_MLME_NEIGHBORREPRESP_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_NEIGHBORREPRESP_CONFIRM);
+ case CSR_MLME_NEIGHBORREPRESP_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_NEIGHBORREPRESP_INDICATION);
+ case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION);
+ case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TRIGGERED_GET_REQUEST);
+ case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TRIGGERED_GET_CONFIRM);
+ case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TRIGGERED_GET_REQUEST);
+ case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TRIGGERED_GET_CONFIRM);
+ case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_TRIGGERED_GET_INDICATION);
+ case CSR_MLME_PING_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PING_REQUEST);
+ case CSR_MLME_PING_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PING_CONFIRM);
+ case CSR_MLME_PING_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PING_RESPONSE);
+ case CSR_MLME_PING_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PING_INDICATION);
+ case CSR_MLME_VSPECIFIC_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_VSPECIFIC_REQUEST);
+ case CSR_MLME_ADD_WDS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_WDS_REQUEST);
+ case CSR_MLME_ADD_WDS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_WDS_CONFIRM);
+ case CSR_MLME_DEL_WDS_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_WDS_REQUEST);
+ case CSR_MLME_DEL_WDS_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_WDS_CONFIRM);
+ case CSR_DS_UNITDATA_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DS_UNITDATA_REQUEST);
+ case CSR_DS_UNITDATA_RESPONSE_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DS_UNITDATA_RESPONSE);
+ case CSR_DS_UNITDATA_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DS_UNITDATA_INDICATION);
+ case CSR_DS_UNITDATA_CANCEL_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DS_UNITDATA_CANCEL_INDICATION);
+ case CSR_DS_STA_NOTIFY_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DS_STA_NOTIFY_REQUEST);
+ case CSR_DEBUG_STRING_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_STRING_INDICATION);
+ case CSR_DEBUG_WORD16_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_WORD16_INDICATION);
+ case CSR_DEBUG_GENERIC_REQUEST_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_REQUEST);
+ case CSR_DEBUG_GENERIC_CONFIRM_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_CONFIRM);
+ case CSR_DEBUG_GENERIC_INDICATION_ID:
+ return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_INDICATION);
+ default:
+ return 0;
+ }
+}
+
+int SigGetDataRefs(CSR_SIGNAL* aSignal, CSR_DATAREF** aDataRef)
+{
+ int numRefs = 0;
+
+ switch(aSignal->SignalPrimitiveHeader.SignalId)
+ {
+ case CSR_MA_UNITDATA_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataRequest.Data;
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataRequest.Dummydataref2;
+ break;
+ case CSR_MA_UNITDATA_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataConfirm.Dummydataref2;
+ break;
+ case CSR_MA_UNITDATA_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataIndication.Data;
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataIndication.Dummydataref2;
+ break;
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MaSniffdataIndication.Data;
+ aDataRef[numRefs++] = &aSignal->u.MaSniffdataIndication.Dummydataref2;
+ break;
+ case CSR_MA_UNITDATA_CANCEL_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataCancelRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MaUnitdataCancelRequest.Dummydataref2;
+ break;
+ case CSR_MLME_RESET_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResetRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResetRequest.Dummydataref2;
+ break;
+ case CSR_MLME_RESET_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResetConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResetConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_GET_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetRequest.MibAttribute;
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetRequest.Dummydataref2;
+ break;
+ case CSR_MLME_GET_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetConfirm.MibAttributeValue;
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_SET_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetRequest.MibAttributeValue;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetRequest.Dummydataref2;
+ break;
+ case CSR_MLME_SET_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetConfirm.MibAttributeValue;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_GET_NEXT_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetNextRequest.MibAttribute;
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetNextRequest.Dummydataref2;
+ break;
+ case CSR_MLME_GET_NEXT_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetNextConfirm.MibAttributeValue;
+ aDataRef[numRefs++] = &aSignal->u.MlmeGetNextConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_POWERMGT_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePowermgtRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmePowermgtRequest.Dummydataref2;
+ break;
+ case CSR_MLME_POWERMGT_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePowermgtConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmePowermgtConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_SCAN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanRequest.ChannelList;
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanRequest.InformationElements;
+ break;
+ case CSR_MLME_SCAN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_SCAN_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanIndication.Dummydataref2;
+ break;
+ case CSR_MLME_JOIN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeJoinRequest.ScanInformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeJoinRequest.StaInformationElements;
+ break;
+ case CSR_MLME_JOIN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeJoinConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeJoinConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_AUTHENTICATE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateRequest.Dummydataref2;
+ break;
+ case CSR_MLME_AUTHENTICATE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_AUTHENTICATE_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateResponse.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateResponse.Dummydataref2;
+ break;
+ case CSR_MLME_AUTHENTICATE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAuthenticateIndication.Dummydataref2;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeauthenticateRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeauthenticateRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeauthenticateConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeauthenticateConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DEAUTHENTICATE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeauthenticateIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeauthenticateIndication.Dummydataref2;
+ break;
+ case CSR_MLME_ASSOCIATE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateRequest.Dummydataref2;
+ break;
+ case CSR_MLME_ASSOCIATE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_ASSOCIATE_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateResponse.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateResponse.Dummydataref2;
+ break;
+ case CSR_MLME_ASSOCIATE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAssociateIndication.Dummydataref2;
+ break;
+ case CSR_MLME_REASSOCIATE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateRequest.Dummydataref2;
+ break;
+ case CSR_MLME_REASSOCIATE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_REASSOCIATE_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateResponse.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateResponse.Dummydataref2;
+ break;
+ case CSR_MLME_REASSOCIATE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeReassociateIndication.Dummydataref2;
+ break;
+ case CSR_MLME_DISASSOCIATE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDisassociateRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDisassociateRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DISASSOCIATE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDisassociateConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDisassociateConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DISASSOCIATE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDisassociateIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDisassociateIndication.Dummydataref2;
+ break;
+ case CSR_MLME_START_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeStartRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeStartRequest.Dummydataref2;
+ break;
+ case CSR_MLME_START_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeStartConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeStartConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_ADDTS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsRequest.Dummydataref2;
+ break;
+ case CSR_MLME_ADDTS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_ADDTS_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsResponse.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsResponse.Dummydataref2;
+ break;
+ case CSR_MLME_ADDTS_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddtsIndication.Dummydataref2;
+ break;
+ case CSR_MLME_DELTS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeltsRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeltsRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DELTS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeltsConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeltsConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DELTS_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeltsIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeltsIndication.Dummydataref2;
+ break;
+ case CSR_MLME_DLS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DLS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsConfirm.SupportedRates;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DLS_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsIndication.SupportedRates;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsIndication.Dummydataref2;
+ break;
+ case CSR_MLME_DLSTEARDOWN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsteardownRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsteardownRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DLSTEARDOWN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsteardownConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsteardownConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DLSTEARDOWN_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsteardownIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDlsteardownIndication.Dummydataref2;
+ break;
+ case CSR_MLME_HL_SYNC_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncRequest.Dummydataref2;
+ break;
+ case CSR_MLME_HL_SYNC_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_HL_SYNC_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncIndication.Dummydataref2;
+ break;
+ case CSR_MLME_ADDBA_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaRequest.Dummydataref2;
+ break;
+ case CSR_MLME_ADDBA_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_ADDBA_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaResponse.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaResponse.Dummydataref2;
+ break;
+ case CSR_MLME_ADDBA_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddbaIndication.Dummydataref2;
+ break;
+ case CSR_MLME_DELBA_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelbaRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelbaRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DELBA_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelbaConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelbaConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DELBA_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelbaIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelbaIndication.Dummydataref2;
+ break;
+ case CSR_MLME_SCHEDULE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeScheduleRequest.ScheduleElement;
+ aDataRef[numRefs++] = &aSignal->u.MlmeScheduleRequest.Dummydataref2;
+ break;
+ case CSR_MLME_SCHEDULE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeScheduleConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeScheduleConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_SCHEDULE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeScheduleIndication.ScheduleElement;
+ aDataRef[numRefs++] = &aSignal->u.MlmeScheduleIndication.Dummydataref2;
+ break;
+ case CSR_MLME_MREQUEST_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMrequestRequest.MeasurementRequestSet;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMrequestRequest.InformationElements;
+ break;
+ case CSR_MLME_MREQUEST_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMrequestConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMrequestConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_MREQUEST_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMrequestIndication.MeasurementRequestSet;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMrequestIndication.InformationElements;
+ break;
+ case CSR_MLME_MEASURE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMeasureRequest.MeasurementRequestSet;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMeasureRequest.Dummydataref2;
+ break;
+ case CSR_MLME_MEASURE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMeasureConfirm.MeasurementReportSet;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMeasureConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_MREPORT_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMreportRequest.MeasurementReportSet;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMreportRequest.InformationElements;
+ break;
+ case CSR_MLME_MREPORT_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMreportConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMreportConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_MREPORT_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMreportIndication.MeasurementReportSet;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMreportIndication.InformationElements;
+ break;
+ case CSR_MLME_CHANNELSWITCH_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchRequest.Dummydataref2;
+ break;
+ case CSR_MLME_CHANNELSWITCH_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_CHANNELSWITCH_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchResponse.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchResponse.Dummydataref2;
+ break;
+ case CSR_MLME_CHANNELSWITCH_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeChannelswitchIndication.Dummydataref2;
+ break;
+ case CSR_MLME_TPCADAPT_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeTpcadaptRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeTpcadaptRequest.Dummydataref2;
+ break;
+ case CSR_MLME_TPCADAPT_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeTpcadaptConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeTpcadaptConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_SETKEYS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysRequest.Key;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysRequest.Dummydataref2;
+ break;
+ case CSR_MLME_SETKEYS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DELETEKEYS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DELETEKEYS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_MICHAELMICFAILURE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeMichaelmicfailureIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeMichaelmicfailureIndication.Dummydataref2;
+ break;
+ case CSR_MLME_EAPOL_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeEapolRequest.Data;
+ aDataRef[numRefs++] = &aSignal->u.MlmeEapolRequest.Dummydataref2;
+ break;
+ case CSR_MLME_EAPOL_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeEapolConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeEapolConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_STAKEYESTABLISHED_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeStakeyestablishedIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeStakeyestablishedIndication.Dummydataref2;
+ break;
+ case CSR_MLME_SETPROTECTION_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetprotectionRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetprotectionRequest.Dummydataref2;
+ break;
+ case CSR_MLME_SETPROTECTION_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetprotectionConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetprotectionConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeProtectedframedroppedIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeProtectedframedroppedIndication.Dummydataref2;
+ break;
+ case CSR_MLME_SNIFFJOIN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSniffjoinRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSniffjoinRequest.Dummydataref2;
+ break;
+ case CSR_MLME_SNIFFJOIN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSniffjoinConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSniffjoinConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_CONNECTED_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeConnectedIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeConnectedIndication.Dummydataref2;
+ break;
+ case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanCancelRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeScanCancelRequest.Dummydataref2;
+ break;
+ case CSR_MLME_LINKMEASURE_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeLinkmeasureRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeLinkmeasureRequest.Dummydataref2;
+ break;
+ case CSR_MLME_LINKMEASURE_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeLinkmeasureConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeLinkmeasureConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelRequest.Dummydataref2;
+ break;
+ case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicRequest.DownlinkInformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicRequest.UplinkInformationElements;
+ break;
+ case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanRequest.ChannelList;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanRequest.InformationElements;
+ break;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanIndication.Dummydataref2;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanResultsRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanResultsRequest.Dummydataref2;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanResultsConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanResultsConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanResultsIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanResultsIndication.Dummydataref2;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetUnitdataFilterRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetUnitdataFilterRequest.Dummydataref2;
+ break;
+ case CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetUnitdataFilterConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeSetUnitdataFilterConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_FT_JOIN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeFtJoinRequest.ScanInformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeFtJoinRequest.StaInformationElements;
+ break;
+ case CSR_MLME_FT_JOIN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeFtJoinConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeFtJoinConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestRequest.Dummydataref2;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestResponse.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestResponse.Dummydataref2;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestIndication.Dummydataref2;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestLocalRequest.ResourceDescriptors;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestLocalRequest.Dummydataref2;
+ break;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestLocalConfirm.ResourceDescriptors;
+ aDataRef[numRefs++] = &aSignal->u.MlmeResourceRequestLocalConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeRemoteRequestRequest.ContentOfFtActionFrame;
+ aDataRef[numRefs++] = &aSignal->u.MlmeRemoteRequestRequest.Dummydataref2;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeRemoteRequestConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeRemoteRequestConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_REMOTE_REQUEST_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeRemoteRequestIndication.ContentOfFtActionFrame;
+ aDataRef[numRefs++] = &aSignal->u.MlmeRemoteRequestIndication.Dummydataref2;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanRequest.Dummydataref2;
+ break;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborrepreqRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborrepreqRequest.Dummydataref2;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborrepreqConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborrepreqConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_NEIGHBORREPREQ_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborrepreqIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborrepreqIndication.Dummydataref2;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborreprespRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborreprespRequest.Dummydataref2;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborreprespConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborreprespConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_NEIGHBORREPRESP_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborreprespIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeNeighborreprespIndication.Dummydataref2;
+ break;
+ case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanDoneIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanDoneIndication.Dummydataref2;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetRequest.MibAttribute;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetRequest.Dummydataref2;
+ break;
+ case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeTriggeredGetIndication.MibAttributeValue;
+ aDataRef[numRefs++] = &aSignal->u.MlmeTriggeredGetIndication.Dummydataref2;
+ break;
+ case CSR_MLME_PING_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePingRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmePingRequest.Dummydataref2;
+ break;
+ case CSR_MLME_PING_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePingConfirm.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmePingConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_PING_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePingResponse.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmePingResponse.Dummydataref2;
+ break;
+ case CSR_MLME_PING_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmePingIndication.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmePingIndication.Dummydataref2;
+ break;
+ case CSR_MLME_VSPECIFIC_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeVspecificRequest.InformationElements;
+ aDataRef[numRefs++] = &aSignal->u.MlmeVspecificRequest.Dummydataref2;
+ break;
+ case CSR_MLME_ADD_WDS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddWdsRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddWdsRequest.Dummydataref2;
+ break;
+ case CSR_MLME_ADD_WDS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddWdsConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeAddWdsConfirm.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_WDS_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelWdsRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelWdsRequest.Dummydataref2;
+ break;
+ case CSR_MLME_DEL_WDS_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelWdsConfirm.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.MlmeDelWdsConfirm.Dummydataref2;
+ break;
+ case CSR_DS_UNITDATA_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataRequest.Data;
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataRequest.Dummydataref2;
+ break;
+ case CSR_DS_UNITDATA_RESPONSE_ID:
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataResponse.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataResponse.Dummydataref2;
+ break;
+ case CSR_DS_UNITDATA_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataIndication.Data;
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataIndication.Dummydataref2;
+ break;
+ case CSR_DS_UNITDATA_CANCEL_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataCancelIndication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.DsUnitdataCancelIndication.Dummydataref2;
+ break;
+ case CSR_DS_STA_NOTIFY_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.DsStaNotifyRequest.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.DsStaNotifyRequest.Dummydataref2;
+ break;
+ case CSR_DEBUG_STRING_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.DebugStringIndication.DebugMessage;
+ aDataRef[numRefs++] = &aSignal->u.DebugStringIndication.Dummydataref2;
+ break;
+ case CSR_DEBUG_WORD16_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.DebugWord16Indication.Dummydataref1;
+ aDataRef[numRefs++] = &aSignal->u.DebugWord16Indication.Dummydataref2;
+ break;
+ case CSR_DEBUG_GENERIC_REQUEST_ID:
+ aDataRef[numRefs++] = &aSignal->u.DebugGenericRequest.DebugVariable;
+ aDataRef[numRefs++] = &aSignal->u.DebugGenericRequest.Dummydataref2;
+ break;
+ case CSR_DEBUG_GENERIC_CONFIRM_ID:
+ aDataRef[numRefs++] = &aSignal->u.DebugGenericConfirm.DebugVariable;
+ aDataRef[numRefs++] = &aSignal->u.DebugGenericConfirm.Dummydataref2;
+ break;
+ case CSR_DEBUG_GENERIC_INDICATION_ID:
+ aDataRef[numRefs++] = &aSignal->u.DebugGenericIndication.DebugVariable;
+ aDataRef[numRefs++] = &aSignal->u.DebugGenericIndication.Dummydataref2;
+ break;
+ default:
+ return 0;
+ }
+ return numRefs;
+}
+
+uint32 SigGetFilterPos(uint16 aSigID)
+{
+ switch(aSigID)
+ {
+ case CSR_MA_UNITDATA_REQUEST_ID:
+ return 0x00000001;
+ case CSR_MA_UNITDATA_CONFIRM_ID:
+ return 0x00000002;
+ case CSR_MA_UNITDATA_INDICATION_ID:
+ return 0x00000004;
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+ return 0x00000008;
+ case CSR_MA_UNITDATA_CANCEL_REQUEST_ID:
+ return 0x00000010;
+ case CSR_MLME_RESET_REQUEST_ID:
+ return 0x00000020;
+ case CSR_MLME_RESET_CONFIRM_ID:
+ return 0x00000040;
+ case CSR_MLME_GET_REQUEST_ID:
+ return 0x00000080;
+ case CSR_MLME_GET_CONFIRM_ID:
+ return 0x00000100;
+ case CSR_MLME_SET_REQUEST_ID:
+ return 0x00000200;
+ case CSR_MLME_SET_CONFIRM_ID:
+ return 0x00000400;
+ case CSR_MLME_GET_NEXT_REQUEST_ID:
+ return 0x00000800;
+ case CSR_MLME_GET_NEXT_CONFIRM_ID:
+ return 0x00001000;
+ case CSR_MLME_POWERMGT_REQUEST_ID:
+ return 0x00002000;
+ case CSR_MLME_POWERMGT_CONFIRM_ID:
+ return 0x00004000;
+ case CSR_MLME_SCAN_REQUEST_ID:
+ return 0x00008000;
+ case CSR_MLME_SCAN_CONFIRM_ID:
+ return 0x00010001;
+ case CSR_MLME_SCAN_INDICATION_ID:
+ return 0x00010002;
+ case CSR_MLME_JOIN_REQUEST_ID:
+ return 0x00010004;
+ case CSR_MLME_JOIN_CONFIRM_ID:
+ return 0x00010008;
+ case CSR_MLME_AUTHENTICATE_REQUEST_ID:
+ return 0x00010010;
+ case CSR_MLME_AUTHENTICATE_CONFIRM_ID:
+ return 0x00010020;
+ case CSR_MLME_AUTHENTICATE_RESPONSE_ID:
+ return 0x00010040;
+ case CSR_MLME_AUTHENTICATE_INDICATION_ID:
+ return 0x00010080;
+ case CSR_MLME_DEAUTHENTICATE_REQUEST_ID:
+ return 0x00010100;
+ case CSR_MLME_DEAUTHENTICATE_CONFIRM_ID:
+ return 0x00010200;
+ case CSR_MLME_DEAUTHENTICATE_INDICATION_ID:
+ return 0x00010400;
+ case CSR_MLME_ASSOCIATE_REQUEST_ID:
+ return 0x00010800;
+ case CSR_MLME_ASSOCIATE_CONFIRM_ID:
+ return 0x00011000;
+ case CSR_MLME_ASSOCIATE_RESPONSE_ID:
+ return 0x00012000;
+ case CSR_MLME_ASSOCIATE_INDICATION_ID:
+ return 0x00014000;
+ case CSR_MLME_REASSOCIATE_REQUEST_ID:
+ return 0x00018000;
+ case CSR_MLME_REASSOCIATE_CONFIRM_ID:
+ return 0x00020001;
+ case CSR_MLME_REASSOCIATE_RESPONSE_ID:
+ return 0x00020002;
+ case CSR_MLME_REASSOCIATE_INDICATION_ID:
+ return 0x00020004;
+ case CSR_MLME_DISASSOCIATE_REQUEST_ID:
+ return 0x00020008;
+ case CSR_MLME_DISASSOCIATE_CONFIRM_ID:
+ return 0x00020010;
+ case CSR_MLME_DISASSOCIATE_INDICATION_ID:
+ return 0x00020020;
+ case CSR_MLME_START_REQUEST_ID:
+ return 0x00020040;
+ case CSR_MLME_START_CONFIRM_ID:
+ return 0x00020080;
+ case CSR_MLME_ADDTS_REQUEST_ID:
+ return 0x00020100;
+ case CSR_MLME_ADDTS_CONFIRM_ID:
+ return 0x00020200;
+ case CSR_MLME_ADDTS_RESPONSE_ID:
+ return 0x00020400;
+ case CSR_MLME_ADDTS_INDICATION_ID:
+ return 0x00020800;
+ case CSR_MLME_DELTS_REQUEST_ID:
+ return 0x00021000;
+ case CSR_MLME_DELTS_CONFIRM_ID:
+ return 0x00022000;
+ case CSR_MLME_DELTS_INDICATION_ID:
+ return 0x00024000;
+ case CSR_MLME_DLS_REQUEST_ID:
+ return 0x00028000;
+ case CSR_MLME_DLS_CONFIRM_ID:
+ return 0x00030001;
+ case CSR_MLME_DLS_INDICATION_ID:
+ return 0x00030002;
+ case CSR_MLME_DLSTEARDOWN_REQUEST_ID:
+ return 0x00030004;
+ case CSR_MLME_DLSTEARDOWN_CONFIRM_ID:
+ return 0x00030008;
+ case CSR_MLME_DLSTEARDOWN_INDICATION_ID:
+ return 0x00030010;
+ case CSR_MLME_HL_SYNC_REQUEST_ID:
+ return 0x00030020;
+ case CSR_MLME_HL_SYNC_CONFIRM_ID:
+ return 0x00030040;
+ case CSR_MLME_HL_SYNC_INDICATION_ID:
+ return 0x00030080;
+ case CSR_MLME_ADDBA_REQUEST_ID:
+ return 0x00030100;
+ case CSR_MLME_ADDBA_CONFIRM_ID:
+ return 0x00030200;
+ case CSR_MLME_ADDBA_RESPONSE_ID:
+ return 0x00030400;
+ case CSR_MLME_ADDBA_INDICATION_ID:
+ return 0x00030800;
+ case CSR_MLME_DELBA_REQUEST_ID:
+ return 0x00031000;
+ case CSR_MLME_DELBA_CONFIRM_ID:
+ return 0x00032000;
+ case CSR_MLME_DELBA_INDICATION_ID:
+ return 0x00034000;
+ case CSR_MLME_SCHEDULE_REQUEST_ID:
+ return 0x00038000;
+ case CSR_MLME_SCHEDULE_CONFIRM_ID:
+ return 0x00040001;
+ case CSR_MLME_SCHEDULE_INDICATION_ID:
+ return 0x00040002;
+ case CSR_MLME_MREQUEST_REQUEST_ID:
+ return 0x00040004;
+ case CSR_MLME_MREQUEST_CONFIRM_ID:
+ return 0x00040008;
+ case CSR_MLME_MREQUEST_INDICATION_ID:
+ return 0x00040010;
+ case CSR_MLME_MEASURE_REQUEST_ID:
+ return 0x00040020;
+ case CSR_MLME_MEASURE_CONFIRM_ID:
+ return 0x00040040;
+ case CSR_MLME_MREPORT_REQUEST_ID:
+ return 0x00040080;
+ case CSR_MLME_MREPORT_CONFIRM_ID:
+ return 0x00040100;
+ case CSR_MLME_MREPORT_INDICATION_ID:
+ return 0x00040200;
+ case CSR_MLME_CHANNELSWITCH_REQUEST_ID:
+ return 0x00040400;
+ case CSR_MLME_CHANNELSWITCH_CONFIRM_ID:
+ return 0x00040800;
+ case CSR_MLME_CHANNELSWITCH_RESPONSE_ID:
+ return 0x00041000;
+ case CSR_MLME_CHANNELSWITCH_INDICATION_ID:
+ return 0x00042000;
+ case CSR_MLME_TPCADAPT_REQUEST_ID:
+ return 0x00044000;
+ case CSR_MLME_TPCADAPT_CONFIRM_ID:
+ return 0x00048000;
+ case CSR_MLME_SETKEYS_REQUEST_ID:
+ return 0x00050001;
+ case CSR_MLME_SETKEYS_CONFIRM_ID:
+ return 0x00050002;
+ case CSR_MLME_DELETEKEYS_REQUEST_ID:
+ return 0x00050004;
+ case CSR_MLME_DELETEKEYS_CONFIRM_ID:
+ return 0x00050008;
+ case CSR_MLME_MICHAELMICFAILURE_INDICATION_ID:
+ return 0x00050010;
+ case CSR_MLME_EAPOL_REQUEST_ID:
+ return 0x00050020;
+ case CSR_MLME_EAPOL_CONFIRM_ID:
+ return 0x00050040;
+ case CSR_MLME_STAKEYESTABLISHED_INDICATION_ID:
+ return 0x00050080;
+ case CSR_MLME_SETPROTECTION_REQUEST_ID:
+ return 0x00050100;
+ case CSR_MLME_SETPROTECTION_CONFIRM_ID:
+ return 0x00050200;
+ case CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID:
+ return 0x00050400;
+ case CSR_MLME_SNIFFJOIN_REQUEST_ID:
+ return 0x00050800;
+ case CSR_MLME_SNIFFJOIN_CONFIRM_ID:
+ return 0x00051000;
+ case CSR_MLME_CONNECTED_INDICATION_ID:
+ return 0x00052000;
+ case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
+ return 0x00054000;
+ case CSR_MLME_LINKMEASURE_REQUEST_ID:
+ return 0x00058000;
+ case CSR_MLME_LINKMEASURE_CONFIRM_ID:
+ return 0x00060001;
+ case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
+ return 0x00060002;
+ case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
+ return 0x00060004;
+ case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
+ return 0x00060008;
+ case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
+ return 0x00060010;
+ case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
+ return 0x00060020;
+ case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
+ return 0x00060040;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
+ return 0x00060080;
+ case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
+ return 0x00060100;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
+ return 0x00060200;
+ case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
+ return 0x00060400;
+ case CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID:
+ return 0x00060800;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID:
+ return 0x00061000;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID:
+ return 0x00062000;
+ case CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID:
+ return 0x00064000;
+ case CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID:
+ return 0x00068000;
+ case CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID:
+ return 0x00070001;
+ case CSR_MLME_FT_JOIN_REQUEST_ID:
+ return 0x00070002;
+ case CSR_MLME_FT_JOIN_CONFIRM_ID:
+ return 0x00070004;
+ case CSR_MLME_RESOURCE_REQUEST_REQUEST_ID:
+ return 0x00070008;
+ case CSR_MLME_RESOURCE_REQUEST_CONFIRM_ID:
+ return 0x00070010;
+ case CSR_MLME_RESOURCE_REQUEST_RESPONSE_ID:
+ return 0x00070020;
+ case CSR_MLME_RESOURCE_REQUEST_INDICATION_ID:
+ return 0x00070040;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_REQUEST_ID:
+ return 0x00070080;
+ case CSR_MLME_RESOURCE_REQUEST_LOCAL_CONFIRM_ID:
+ return 0x00070100;
+ case CSR_MLME_REMOTE_REQUEST_REQUEST_ID:
+ return 0x00070200;
+ case CSR_MLME_REMOTE_REQUEST_CONFIRM_ID:
+ return 0x00070400;
+ case CSR_MLME_REMOTE_REQUEST_INDICATION_ID:
+ return 0x00070800;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
+ return 0x00071000;
+ case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
+ return 0x00072000;
+ case CSR_MLME_NEIGHBORREPREQ_REQUEST_ID:
+ return 0x00074000;
+ case CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID:
+ return 0x00078000;
+ case CSR_MLME_NEIGHBORREPREQ_INDICATION_ID:
+ return 0x00080001;
+ case CSR_MLME_NEIGHBORREPRESP_REQUEST_ID:
+ return 0x00080002;
+ case CSR_MLME_NEIGHBORREPRESP_CONFIRM_ID:
+ return 0x00080004;
+ case CSR_MLME_NEIGHBORREPRESP_INDICATION_ID:
+ return 0x00080008;
+ case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
+ return 0x00080010;
+ case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
+ return 0x00080020;
+ case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
+ return 0x00080040;
+ case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
+ return 0x00080080;
+ case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
+ return 0x00080100;
+ case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
+ return 0x00080200;
+ case CSR_MLME_PING_REQUEST_ID:
+ return 0x00080400;
+ case CSR_MLME_PING_CONFIRM_ID:
+ return 0x00080800;
+ case CSR_MLME_PING_RESPONSE_ID:
+ return 0x00081000;
+ case CSR_MLME_PING_INDICATION_ID:
+ return 0x00082000;
+ case CSR_MLME_VSPECIFIC_REQUEST_ID:
+ return 0x00084000;
+ case CSR_MLME_ADD_WDS_REQUEST_ID:
+ return 0x00088000;
+ case CSR_MLME_ADD_WDS_CONFIRM_ID:
+ return 0x00090001;
+ case CSR_MLME_DEL_WDS_REQUEST_ID:
+ return 0x00090002;
+ case CSR_MLME_DEL_WDS_CONFIRM_ID:
+ return 0x00090004;
+ case CSR_DS_UNITDATA_REQUEST_ID:
+ return 0x00090008;
+ case CSR_DS_UNITDATA_RESPONSE_ID:
+ return 0x00090010;
+ case CSR_DS_UNITDATA_INDICATION_ID:
+ return 0x00090020;
+ case CSR_DS_UNITDATA_CANCEL_INDICATION_ID:
+ return 0x00090040;
+ case CSR_DS_STA_NOTIFY_REQUEST_ID:
+ return 0x00090080;
+ case CSR_DEBUG_STRING_INDICATION_ID:
+ return 0x00090100;
+ case CSR_DEBUG_WORD16_INDICATION_ID:
+ return 0x00090200;
+ case CSR_DEBUG_GENERIC_REQUEST_ID:
+ return 0x00090400;
+ case CSR_DEBUG_GENERIC_CONFIRM_ID:
+ return 0x00090800;
+ case CSR_DEBUG_GENERIC_INDICATION_ID:
+ return 0x00091000;
+ default:
+ break;
+ }
+ return 0xffffffff;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.c
new file mode 100644
index 0000000..25ebdac
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.c
@@ -0,0 +1,447 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: ta_sampling.c
+ *
+ * PURPOSE:
+ * The traffic analysis sampling module.
+ * This gathers data which is sent to the SME and used to analyse
+ * the traffic behaviour.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Provides:
+ * unifi_ta_sampling_init - Initialise the internal state
+ * unifi_ta_sample - Sampling function, call this for every data packet
+ *
+ * Calls these external functions which must be provided:
+ * unifi_ta_indicate_sampling - Pass sample data to the SME.
+ * unifi_ta_indicate_protocol - Report certain data packet types to the SME.
+ * ---------------------------------------------------------------------------
+ */
+
+#include "card_sdio.h"
+
+/* Maximum number of Tx frames we store each CYCLE_1, for detecting period */
+#define TA_MAX_INTERVALS_IN_C1 100
+
+/* Number of intervals in CYCLE_1 (one second), for detecting periodic */
+/* Must match size of unifi_traffic_stats.intervals - 1 */
+#define TA_INTERVALS_NUM 10
+
+/* Step (in msecs) between intervals, for detecting periodic */
+/* We are only interested in periods up to 100ms, i.e. between beacons */
+/* This is correct for TA_INTERVALS_NUM=10 */
+#define TA_INTERVALS_STEP 10
+
+
+
+enum ta_frame_identity {
+ TA_FRAME_UNKNOWN,
+ TA_FRAME_ETHERNET_UNINTERESTING,
+ TA_FRAME_ETHERNET_INTERESTING
+};
+
+
+
+
+#define TA_ETHERNET_TYPE_OFFSET 6
+#define TA_LLC_HEADER_SIZE 8
+#define TA_IP_TYPE_OFFSET 17
+#define TA_UDP_SOURCE_PORT_OFFSET 28
+#define TA_UDP_DEST_PORT_OFFSET (TA_UDP_SOURCE_PORT_OFFSET + 2)
+#define TA_BOOTP_CLIENT_MAC_ADDR_OFFSET 64
+#define TA_DHCP_MESSAGE_TYPE_OFFSET 278
+#define TA_DHCP_MESSAGE_TYPE_ACK 0x05
+#define TA_PROTO_TYPE_IP 0x0800
+#define TA_PROTO_TYPE_EAP 0x888E
+#define TA_PROTO_TYPE_ARP 0x0806
+#define TA_IP_TYPE_UDP 0x11
+#define TA_UDP_PORT_BOOTPC 0x0044
+#define TA_UDP_PORT_BOOTPS 0x0043
+#define TA_EAPOL_TYPE_OFFSET 9
+#define TA_EAPOL_TYPE_START 0x01
+
+static const unsigned char snap_802_2[3] = { 0xAA, 0xAA, 0x03 };
+static const unsigned char oui_rfc1042[3] = { 0x00, 0x00, 0x00 };
+static const unsigned char oui_8021h[3] = { 0x00, 0x00, 0xf8 };
+static const unsigned char aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 };
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ta_detect_protocol
+ *
+ * Internal only.
+ * Detects a specific protocol in a frame and indicates a TA event.
+ *
+ * Arguments:
+ * ta The pointer to the TA module.
+ * direction The direction of the frame (tx or rx).
+ * data Pointer to the structure that contains the data.
+ *
+ * Returns:
+ * None
+ * ---------------------------------------------------------------------------
+ */
+static enum ta_frame_identity
+ta_detect_protocol(card_t *card, unifi_protocol_direction direction,
+ const bulk_data_desc_t* data,
+ const unsigned char *saddr,
+ const unsigned char *sta_macaddr)
+{
+ ta_data_t *tad = &card->ta_sampling;
+ unsigned int proto;
+ unsigned int source_port, dest_port;
+ unifi_MACAddress srcAddress;
+
+ if (data->data_length < TA_LLC_HEADER_SIZE) {
+ return TA_FRAME_UNKNOWN;
+ }
+
+ if (memcmp(data->os_data_ptr, snap_802_2, 3)) {
+ return TA_FRAME_UNKNOWN;
+ }
+
+ if (tad->packet_filter & unifi_TrafficPacketCustom) {
+ /*
+ * TODO: Use the custom filter to detect interesting frames.
+ */
+ }
+
+ if (!memcmp(data->os_data_ptr+3, oui_rfc1042, 3) ||
+ !memcmp(data->os_data_ptr+3, oui_8021h, 3)) {
+
+ proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) +
+ data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1];
+
+ /* The only interesting IP frames are the DHCP */
+ if (proto == TA_PROTO_TYPE_IP) {
+ /* detect DHCP frames */
+ if (tad->packet_filter & unifi_TrafficPacketDhcp) {
+
+ if (data->data_length > TA_IP_TYPE_OFFSET) {
+ /* DHCP frames are UDP frames with BOOTP ports */
+ if (data->os_data_ptr[TA_IP_TYPE_OFFSET] == TA_IP_TYPE_UDP) {
+
+ if (data->data_length > TA_UDP_DEST_PORT_OFFSET) {
+ source_port = (data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET] * 256) +
+ data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET + 1];
+ dest_port = (data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET] * 256) +
+ data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET + 1];
+
+ if (((source_port == TA_UDP_PORT_BOOTPC) && (dest_port == TA_UDP_PORT_BOOTPS)) ||
+ ((source_port == TA_UDP_PORT_BOOTPS) && (dest_port == TA_UDP_PORT_BOOTPC))) {
+
+ /* The DHCP should have at least a message type (request, ack, nack, etc) */
+ if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6) {
+ memcpy(srcAddress.data, saddr, 6);
+
+ if (direction == unifi_traffic_tx) {
+ unifi_ta_indicate_protocol(card->ospriv,
+ unifi_TrafficPacketDhcp,
+ direction,
+ &srcAddress);
+ return TA_FRAME_ETHERNET_UNINTERESTING;
+ }
+
+ /* DHCPACK is a special indication */
+ if (!memcmp(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr, 6)) {
+ if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK) {
+
+ unifi_ta_indicate_protocol(card->ospriv,
+ unifi_TrafficPacketDhcpAck,
+ direction,
+ &srcAddress);
+ } else {
+ unifi_ta_indicate_protocol(card->ospriv,
+ unifi_TrafficPacketDhcp,
+ direction,
+ &srcAddress);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return TA_FRAME_ETHERNET_INTERESTING;
+ }
+
+ /* detect protocol type 0x888E (EAPOL) */
+ if (tad->packet_filter & unifi_TrafficPacketEapol) {
+ if (proto == TA_PROTO_TYPE_EAP) {
+ if ((direction == unifi_traffic_tx) &&
+ (data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] != TA_EAPOL_TYPE_START)) {
+
+ return TA_FRAME_ETHERNET_UNINTERESTING;
+ } else {
+
+ memcpy(srcAddress.data, saddr, 6);
+ unifi_ta_indicate_protocol(card->ospriv,
+ unifi_TrafficPacketEapol,
+ direction, &srcAddress);
+ return TA_FRAME_ETHERNET_UNINTERESTING;
+ }
+ }
+ }
+
+ /* detect protocol type 0x0806 (ARP) */
+ if (tad->packet_filter & unifi_TrafficPacketArp) {
+ if (proto == TA_PROTO_TYPE_ARP) {
+ /* TODO: Are we interested in specific source or destination addresses? */
+ memcpy(srcAddress.data, saddr, 6);
+ unifi_ta_indicate_protocol(card->ospriv,
+ unifi_TrafficPacketArp,
+ direction, &srcAddress);
+ return TA_FRAME_ETHERNET_UNINTERESTING;
+ }
+ }
+
+ return TA_FRAME_ETHERNET_INTERESTING;
+
+ } else if (tad->packet_filter & unifi_TrafficPacketAironet) {
+
+ /* detect Aironet frames */
+ if (!memcmp(data->os_data_ptr+3, aironet_snap, 5)) {
+ memcpy(srcAddress.data, saddr, 6);
+ unifi_ta_indicate_protocol(card->ospriv, unifi_TrafficPacketAironet,
+ direction, &srcAddress);
+ }
+ }
+
+ return TA_FRAME_ETHERNET_UNINTERESTING;
+
+} /* ta_detect_protocol() */
+
+
+
+static void
+tas_reset_data(ta_data_t *tad)
+{
+ int i;
+
+ for (i = 0; i < (TA_INTERVALS_NUM+1); i++) {
+ tad->stats.intervals[i] = 0;
+ }
+
+ tad->stats.rxFramesNum = 0;
+ tad->stats.txFramesNum = 0;
+ tad->stats.rxBytesCount = 0;
+ tad->stats.txBytesCount = 0;
+
+} /* tas_reset_data() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * API.
+ * unifi_ta_sampling_init
+ *
+ * (Re)Initialise the Traffic Analysis sampling module.
+ * Resets the counters and timestamps.
+ *
+ * Arguments:
+ * tad Pointer to a ta_data_t structure containing the
+ * context for this device instance.
+ * drv_priv An opaque pointer that the TA sampling module will
+ * pass in call-outs.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_ta_sampling_init(card_t *card)
+{
+ (void)unifi_ta_configure(card, unifi_TrafficConfigReset, NULL);
+
+ card->ta_sampling.packet_filter = unifi_TrafficPacketNone;
+ card->ta_sampling.traffic_type = unifi_traffic_occasional;
+
+} /* unifi_ta_sampling_init() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * API.
+ * unifi_ta_sample
+ *
+ * Sample a data frame for the TA module.
+ * This function stores all the useful information it can extract from
+ * the frame and detects any specific protocols.
+ *
+ * Arguments:
+ * tad The pointer to the TA sampling context struct.
+ * direction The direction of the frame (rx, tx)
+ * data Pointer to the frame data
+ * saddr Source MAC address of frame.
+ * timestamp Time (in msecs) that the frame was received.
+ *
+ * Returns:
+ * None
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_ta_sample(card_t *card,
+ unifi_protocol_direction direction,
+ const bulk_data_desc_t *data,
+ const unsigned char *saddr,
+ const unsigned char *sta_macaddr,
+ uint32 timestamp)
+{
+ ta_data_t *tad = &card->ta_sampling;
+ enum ta_frame_identity identity;
+
+
+
+
+ /* Step1: Check for specific frames */
+ if (tad->packet_filter != unifi_TrafficPacketNone) {
+ identity = ta_detect_protocol(card, direction, data, saddr, sta_macaddr);
+ } else {
+ identity = TA_FRAME_ETHERNET_INTERESTING;
+ }
+
+
+ /* Step2: Update the information in the current record */
+ if (direction == unifi_traffic_rx) {
+ /* Update the Rx packet count and the throughput count */
+ tad->stats.rxFramesNum++;
+ tad->stats.rxBytesCount += data->data_length;
+ } else {
+ if (identity == TA_FRAME_ETHERNET_INTERESTING) {
+ /*
+ * Store the period between the last and the current frame.
+ * There is not point storing more than TA_MAX_INTERVALS_IN_C1 periods,
+ * the traffic will be bursty or continuous.
+ */
+ if (tad->stats.txFramesNum < TA_MAX_INTERVALS_IN_C1) {
+ unsigned long interval;
+ unsigned int index_in_intervals;
+
+ interval = timestamp - tad->tx_last_ts;
+ tad->tx_last_ts = timestamp;
+ index_in_intervals = (interval + TA_INTERVALS_STEP/2 - 1) / TA_INTERVALS_STEP;
+
+ /* If the interval is interesting, update the t1_intervals count */
+ if (index_in_intervals <= TA_INTERVALS_NUM) {
+ unifi_trace(card->ospriv, UDBG5,
+ "unifi_ta_sample: TX interval=%d index=%d\n",
+ interval, index_in_intervals);
+ tad->stats.intervals[index_in_intervals]++;
+ }
+ }
+ }
+
+ /* Update the Tx packet count... */
+ tad->stats.txFramesNum++;
+ /* ... and the number of bytes for throughput. */
+ tad->stats.txBytesCount += data->data_length;
+ }
+
+ /*
+ * If more than one second has elapsed since the last report, send
+ * another one.
+ */
+ /* Unsigned subtraction handles wrap-around from 0xFFFFFFFF to 0 */
+ if ((timestamp - tad->last_indication_time) >= 1000) {
+ /*
+ * Send the information collected in the stats struct
+ * to the SME and reset the counters.
+ */
+ unifi_ta_indicate_sampling(card->ospriv, &tad->stats);
+ tas_reset_data(tad);
+ tad->last_indication_time = timestamp;
+ }
+
+
+} /* unifi_ta_sample() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * External API.
+ * unifi_ta_configure
+ *
+ * Configures the TA module parameters.
+ *
+ * Arguments:
+ * ta The pointer to the TA module.
+ * config_type The type of the configuration request
+ * config Pointer to the configuration parameters.
+ *
+ * Returns:
+ * 0 on success, error code otherwise
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_ta_configure(card_t *card,
+ unifi_traffic_configtype config_type,
+ const unifi_traffic_config *config)
+{
+ ta_data_t *tad = &card->ta_sampling;
+
+ /* Reinitialise our data when we are reset */
+ if (config_type == unifi_TrafficConfigReset) {
+ /* Reset the stats to zero */
+ tas_reset_data(tad);
+
+ /* Reset the timer variables */
+ tad->tx_last_ts = 0;
+ tad->last_indication_time = 0;
+
+ return 0;
+ }
+
+ if (config_type == unifi_TrafficConfigFilter) {
+ tad->packet_filter = config->packetFilter;
+
+ if (tad->packet_filter & unifi_TrafficPacketCustom) {
+ tad->custom_filter = config->customFilter;
+ }
+
+ return 0;
+ }
+
+ return 0;
+} /* unifi_ta_configure() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * External API.
+ * unifi_ta_classification
+ *
+ * Configures the current TA classification.
+ *
+ * Arguments:
+ * ta The pointer to the TA module.
+ * traffic_type The classification type
+ * period The traffic period if the type is periodic
+ *
+ * Returns:
+ * None
+ * ---------------------------------------------------------------------------
+ */
+void unifi_ta_classification(card_t *card,
+ unifi_traffic_type traffic_type,
+ uint16 period)
+{
+ unifi_trace(card->ospriv, UDBG3,
+ "Changed current ta classification to: %d\n", traffic_type);
+
+ card->ta_sampling.traffic_type = traffic_type;
+}
+
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.h b/unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.h
new file mode 100644
index 0000000..04d0cc0
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/ta_sampling.h
@@ -0,0 +1,54 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: ta_sampling.h
+ *
+ * PURPOSE:
+ * This file contains Traffic Analysis definitions common to the
+ * sampling and analysis modules.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __TA_SAMPLING_H__
+#define __TA_SAMPLING_H__
+
+#include "driver/unifi.h"
+
+
+/*
+ * Context structure to preserve state between calls.
+ */
+typedef struct ta_data {
+
+ /* Current packet filter configuration */
+ uint16 packet_filter;
+
+ /* Current packet custom filter configuration */
+ unifi_traffic_filter custom_filter;
+
+ /* The timestamp of the last tx packet processed. */
+ uint32 tx_last_ts;
+
+ /* The timestamp of the last packet processed. */
+ uint32 last_indication_time;
+
+ /* Statistics */
+ unifi_traffic_stats stats;
+
+ /* Current traffic classification */
+ unifi_traffic_type traffic_type;
+
+} ta_data_t;
+
+
+
+
+void unifi_ta_sampling_init(card_t *card);
+
+
+
+#endif /* __TA_SAMPLING_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/udi.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/udi.c
new file mode 100644
index 0000000..3d16f54
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/udi.c
@@ -0,0 +1,122 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: card_udi.c
+ *
+ * PURPOSE:
+ * Maintain a list of callbacks to log UniFi exchanges to one or more
+ * debug/monitoring client applications.
+ *
+ * NOTES:
+ * Just call the UDI driver log fn directly for now.
+ * When done properly, each open() on the UDI device will install
+ * a log function. We will call all log fns whenever a signal is written
+ * to or read form the UniFi.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "card.h"
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_print_status
+ *
+ * Print status info to given character buffer.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_print_status(card_t *card, char *str)
+{
+ char *p = str;
+ sdio_config_data_t *cfg;
+ unsigned int i, n;
+
+ p += unifi_sprintf(p, "Chip ID %u\n", card->chip_id);
+ p += unifi_sprintf(p, "Chip Version %04X\n", card->chip_version);
+ p += unifi_sprintf(p, "HIP v%u.%u\n",
+ (card->config_data.version >> 8) & 0xFF,
+ card->config_data.version & 0xFF);
+ p += unifi_sprintf(p, "Build %lu: %s\n", card->build_id, card->build_id_string);
+
+
+ cfg = &card->config_data;
+
+ p += unifi_sprintf(p, "sdio ctrl offset %u\n", cfg->sdio_ctrl_offset);
+ p += unifi_sprintf(p, "fromhost sigbuf handle %u\n", cfg->fromhost_sigbuf_handle);
+ p += unifi_sprintf(p, "tohost_sigbuf_handle %u\n", cfg->tohost_sigbuf_handle);
+ p += unifi_sprintf(p, "num_fromhost_sig_frags %u\n", cfg->num_fromhost_sig_frags);
+ p += unifi_sprintf(p, "num_tohost_sig_frags %u\n", cfg->num_tohost_sig_frags);
+ p += unifi_sprintf(p, "num_fromhost_data_slots %u\n", cfg->num_fromhost_data_slots);
+ p += unifi_sprintf(p, "num_tohost_data_slots %u\n", cfg->num_tohost_data_slots);
+ p += unifi_sprintf(p, "data_slot_size %u\n", cfg->data_slot_size);
+
+ /* Added by protocol version 0x0001 */
+ p += unifi_sprintf(p, "overlay_size %u\n", (unsigned int)cfg->overlay_size);
+
+ /* Added by protocol version 0x0300 */
+ p += unifi_sprintf(p, "data_slot_round %u\n", cfg->data_slot_round);
+ p += unifi_sprintf(p, "sig_frag_size %u\n", cfg->sig_frag_size);
+
+ /* Added by protocol version 0x0300 */
+ p += unifi_sprintf(p, "tohost_sig_pad %u\n", cfg->tohost_signal_padding);
+
+ p += unifi_sprintf(p, "\nInternal state:\n");
+
+ p += unifi_sprintf(p, "fhsr: %u\n", card->from_host_signals_r);
+ p += unifi_sprintf(p, "fhsw: %u\n", card->from_host_signals_w);
+ p += unifi_sprintf(p, "thsr: %u\n", card->to_host_signals_r);
+ p += unifi_sprintf(p, "thsw: %u\n", card->to_host_signals_w);
+ p += unifi_sprintf(p, "fh buffer contains: %u signals, %u bytes\n",
+ card->fh_buffer.count,
+ card->fh_buffer.ptr - card->fh_buffer.buf);
+ p += unifi_sprintf(p, "paused: %u\n", card->paused);
+
+ p += unifi_sprintf(p, "fh command q: %u waiting, %u free of %u:\n",
+ q_slots_used(&card->fh_command_queue),
+ q_slots_free(&card->fh_command_queue),
+ UNIFI_SOFT_COMMAND_Q_LENGTH);
+ for (i = 0; i < UNIFI_WME_NO_OF_QS; i++) {
+ p += unifi_sprintf(p, "fh traffic q[%u]: %u waiting, %u free of %u:\n", i,
+ q_slots_used(&card->fh_traffic_queue[i]),
+ q_slots_free(&card->fh_traffic_queue[i]),
+ UNIFI_SOFT_TRAFFIC_Q_LENGTH);
+ }
+
+ p += unifi_sprintf(p, "fh data slots free: %u\n",
+ CardGetFreeFromHostDataSlots(card));
+ p += unifi_sprintf(p, "From host data slots:");
+ n = card->config_data.num_fromhost_data_slots;
+ for (i = 0; i < n; i++) {
+ p += unifi_sprintf(p, " %u", card->from_host_data[i].data_length);
+ }
+ p += unifi_sprintf(p, "\n");
+
+ p += unifi_sprintf(p, "To host data slots:");
+ n = card->config_data.num_tohost_data_slots;
+ for (i = 0; i < n; i++) {
+ p += unifi_sprintf(p, " %u", card->to_host_data[i].data_length);
+ }
+ p += unifi_sprintf(p, "\n");
+
+
+ p += unifi_sprintf(p, "\nStats:\n");
+ p += unifi_sprintf(p, "Total SDIO bytes: R=%llu W=%llu\n",
+ card->sdio_bytes_read,
+ card->sdio_bytes_written);
+
+ p += unifi_sprintf(p, "Interrupts generated: %lu\n", card->unifi_interrupt_seq);
+
+ return (p - str);
+} /* unifi_print_status() */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/unifi_signal_names.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/unifi_signal_names.c
new file mode 100644
index 0000000..f2ba13c
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/unifi_signal_names.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ */
+#include "driver/unifi.h"
+
+
+struct sig_name {
+ int id;
+ const char *name;
+};
+
+static const struct sig_name Unifi_signal_names[] = {
+ { CSR_MA_UNITDATA_REQUEST_ID, "CSR_MA_UNITDATA_REQUEST_ID" },
+ { CSR_MA_UNITDATA_INDICATION_ID, "CSR_MA_UNITDATA_INDICATION_ID" },
+ { CSR_MA_UNITDATA_CONFIRM_ID, "CSR_MA_UNITDATA_CONFIRM_ID" },
+ { CSR_MA_SNIFFDATA_INDICATION_ID, "CSR_MA_SNIFFDATA_INDICATION_ID" },
+ { CSR_MA_UNITDATA_CANCEL_REQUEST_ID, "CSR_MA_UNITDATA_CANCEL_REQUEST_ID" },
+ { CSR_MLME_RESET_REQUEST_ID, "CSR_MLME_RESET_REQUEST_ID" },
+ { CSR_MLME_RESET_CONFIRM_ID, "CSR_MLME_RESET_CONFIRM_ID" },
+ { CSR_MLME_GET_REQUEST_ID, "CSR_MLME_GET_REQUEST_ID" },
+ { CSR_MLME_GET_CONFIRM_ID, "CSR_MLME_GET_CONFIRM_ID" },
+ { CSR_MLME_SET_REQUEST_ID, "CSR_MLME_SET_REQUEST_ID" },
+ { CSR_MLME_SET_CONFIRM_ID, "CSR_MLME_SET_CONFIRM_ID" },
+ { CSR_MLME_GET_NEXT_REQUEST_ID, "CSR_MLME_GET_NEXT_REQUEST_ID" },
+ { CSR_MLME_GET_NEXT_CONFIRM_ID, "CSR_MLME_GET_NEXT_CONFIRM_ID" },
+ { CSR_MLME_POWERMGT_REQUEST_ID, "CSR_MLME_POWERMGT_REQUEST_ID" },
+ { CSR_MLME_POWERMGT_CONFIRM_ID, "CSR_MLME_POWERMGT_CONFIRM_ID" },
+ { CSR_MLME_SCAN_REQUEST_ID, "CSR_MLME_SCAN_REQUEST_ID" },
+ { CSR_MLME_SCAN_CONFIRM_ID, "CSR_MLME_SCAN_CONFIRM_ID" },
+ { CSR_MLME_SCAN_INDICATION_ID, "CSR_MLME_SCAN_INDICATION_ID" },
+ { CSR_MLME_JOIN_REQUEST_ID, "CSR_MLME_JOIN_REQUEST_ID" },
+ { CSR_MLME_JOIN_CONFIRM_ID, "CSR_MLME_JOIN_CONFIRM_ID" },
+ { CSR_MLME_AUTHENTICATE_REQUEST_ID, "CSR_MLME_AUTHENTICATE_REQUEST_ID" },
+ { CSR_MLME_AUTHENTICATE_CONFIRM_ID, "CSR_MLME_AUTHENTICATE_CONFIRM_ID" },
+ { CSR_MLME_AUTHENTICATE_INDICATION_ID, "CSR_MLME_AUTHENTICATE_INDICATION_ID" },
+ { CSR_MLME_DEAUTHENTICATE_REQUEST_ID, "CSR_MLME_DEAUTHENTICATE_REQUEST_ID" },
+ { CSR_MLME_DEAUTHENTICATE_CONFIRM_ID, "CSR_MLME_DEAUTHENTICATE_CONFIRM_ID" },
+ { CSR_MLME_DEAUTHENTICATE_INDICATION_ID, "CSR_MLME_DEAUTHENTICATE_INDICATION_ID" },
+ { CSR_MLME_ASSOCIATE_REQUEST_ID, "CSR_MLME_ASSOCIATE_REQUEST_ID" },
+ { CSR_MLME_ASSOCIATE_CONFIRM_ID, "CSR_MLME_ASSOCIATE_CONFIRM_ID" },
+ { CSR_MLME_ASSOCIATE_INDICATION_ID, "CSR_MLME_ASSOCIATE_INDICATION_ID" },
+ { CSR_MLME_REASSOCIATE_REQUEST_ID, "CSR_MLME_REASSOCIATE_REQUEST_ID" },
+ { CSR_MLME_REASSOCIATE_CONFIRM_ID, "CSR_MLME_REASSOCIATE_CONFIRM_ID" },
+ { CSR_MLME_REASSOCIATE_INDICATION_ID, "CSR_MLME_REASSOCIATE_INDICATION_ID" },
+ { CSR_MLME_DISASSOCIATE_REQUEST_ID, "CSR_MLME_DISASSOCIATE_REQUEST_ID" },
+ { CSR_MLME_DISASSOCIATE_CONFIRM_ID, "CSR_MLME_DISASSOCIATE_CONFIRM_ID" },
+ { CSR_MLME_DISASSOCIATE_INDICATION_ID, "CSR_MLME_DISASSOCIATE_INDICATION_ID" },
+ { CSR_MLME_START_REQUEST_ID, "CSR_MLME_START_REQUEST_ID" },
+ { CSR_MLME_START_CONFIRM_ID, "CSR_MLME_START_CONFIRM_ID" },
+ { CSR_MLME_ADDTS_REQUEST_ID, "CSR_MLME_ADDTS_REQUEST_ID" },
+ { CSR_MLME_ADDTS_CONFIRM_ID, "CSR_MLME_ADDTS_CONFIRM_ID" },
+ { CSR_MLME_ADDTS_RESPONSE_ID, "CSR_MLME_ADDTS_RESPONSE_ID" },
+ { CSR_MLME_ADDTS_INDICATION_ID, "CSR_MLME_ADDTS_INDICATION_ID" },
+ { CSR_MLME_DELTS_REQUEST_ID, "CSR_MLME_DELTS_REQUEST_ID" },
+ { CSR_MLME_DELTS_CONFIRM_ID, "CSR_MLME_DELTS_CONFIRM_ID" },
+ { CSR_MLME_DELTS_INDICATION_ID, "CSR_MLME_DELTS_INDICATION_ID" },
+ { CSR_MLME_DLS_REQUEST_ID, "CSR_MLME_DLS_REQUEST_ID" },
+ { CSR_MLME_DLS_CONFIRM_ID, "CSR_MLME_DLS_CONFIRM_ID" },
+ { CSR_MLME_DLS_INDICATION_ID, "CSR_MLME_DLS_INDICATION_ID" },
+ { CSR_MLME_DLSTEARDOWN_REQUEST_ID, "CSR_MLME_DLSTEARDOWN_REQUEST_ID" },
+ { CSR_MLME_DLSTEARDOWN_CONFIRM_ID, "CSR_MLME_DLSTEARDOWN_CONFIRM_ID" },
+ { CSR_MLME_DLSTEARDOWN_INDICATION_ID, "CSR_MLME_DLSTEARDOWN_INDICATION_ID" },
+ { CSR_MLME_HL_SYNC_REQUEST_ID, "CSR_MLME_HL_SYNC_REQUEST_ID" },
+ { CSR_MLME_HL_SYNC_CONFIRM_ID, "CSR_MLME_HL_SYNC_CONFIRM_ID" },
+ { CSR_MLME_HL_SYNC_INDICATION_ID, "CSR_MLME_HL_SYNC_INDICATION_ID" },
+ { CSR_MLME_ADDBA_REQUEST_ID, "CSR_MLME_ADDBA_REQUEST_ID" },
+ { CSR_MLME_ADDBA_CONFIRM_ID, "CSR_MLME_ADDBA_CONFIRM_ID" },
+ { CSR_MLME_ADDBA_RESPONSE_ID, "CSR_MLME_ADDBA_RESPONSE_ID" },
+ { CSR_MLME_ADDBA_INDICATION_ID, "CSR_MLME_ADDBA_INDICATION_ID" },
+ { CSR_MLME_DELBA_REQUEST_ID, "CSR_MLME_DELBA_REQUEST_ID" },
+ { CSR_MLME_DELBA_CONFIRM_ID, "CSR_MLME_DELBA_CONFIRM_ID" },
+ { CSR_MLME_DELBA_INDICATION_ID, "CSR_MLME_DELBA_INDICATION_ID" },
+ { CSR_MLME_SCHEDULE_REQUEST_ID, "CSR_MLME_SCHEDULE_REQUEST_ID" },
+ { CSR_MLME_SCHEDULE_CONFIRM_ID, "CSR_MLME_SCHEDULE_CONFIRM_ID" },
+ { CSR_MLME_SCHEDULE_INDICATION_ID, "CSR_MLME_SCHEDULE_INDICATION_ID" },
+ { CSR_MLME_MREQUEST_REQUEST_ID, "CSR_MLME_MREQUEST_REQUEST_ID" },
+ { CSR_MLME_MREQUEST_CONFIRM_ID, "CSR_MLME_MREQUEST_CONFIRM_ID" },
+ { CSR_MLME_MREQUEST_INDICATION_ID, "CSR_MLME_MREQUEST_INDICATION_ID" },
+ { CSR_MLME_MEASURE_REQUEST_ID, "CSR_MLME_MEASURE_REQUEST_ID" },
+ { CSR_MLME_MEASURE_CONFIRM_ID, "CSR_MLME_MEASURE_CONFIRM_ID" },
+ { CSR_MLME_MREPORT_REQUEST_ID, "CSR_MLME_MREPORT_REQUEST_ID" },
+ { CSR_MLME_MREPORT_CONFIRM_ID, "CSR_MLME_MREPORT_CONFIRM_ID" },
+ { CSR_MLME_MREPORT_INDICATION_ID, "CSR_MLME_MREPORT_INDICATION_ID" },
+ { CSR_MLME_CHANNELSWITCH_REQUEST_ID, "CSR_MLME_CHANNELSWITCH_REQUEST_ID" },
+ { CSR_MLME_CHANNELSWITCH_CONFIRM_ID, "CSR_MLME_CHANNELSWITCH_CONFIRM_ID" },
+ { CSR_MLME_CHANNELSWITCH_RESPONSE_ID, "CSR_MLME_CHANNELSWITCH_RESPONSE_ID" },
+ { CSR_MLME_CHANNELSWITCH_INDICATION_ID, "CSR_MLME_CHANNELSWITCH_INDICATION_ID" },
+ { CSR_MLME_TPCADAPT_REQUEST_ID, "CSR_MLME_TPCADAPT_REQUEST_ID" },
+ { CSR_MLME_TPCADAPT_CONFIRM_ID, "CSR_MLME_TPCADAPT_CONFIRM_ID" },
+ { CSR_MLME_SETKEYS_REQUEST_ID, "CSR_MLME_SETKEYS_REQUEST_ID" },
+ { CSR_MLME_SETKEYS_CONFIRM_ID, "CSR_MLME_SETKEYS_CONFIRM_ID" },
+ { CSR_MLME_DELETEKEYS_REQUEST_ID, "CSR_MLME_DELETEKEYS_REQUEST_ID" },
+ { CSR_MLME_DELETEKEYS_CONFIRM_ID, "CSR_MLME_DELETEKEYS_CONFIRM_ID" },
+ { CSR_MLME_MICHAELMICFAILURE_INDICATION_ID, "CSR_MLME_MICHAELMICFAILURE_INDICATION_ID" },
+ { CSR_MLME_EAPOL_REQUEST_ID, "CSR_MLME_EAPOL_REQUEST_ID" },
+ { CSR_MLME_EAPOL_CONFIRM_ID, "CSR_MLME_EAPOL_CONFIRM_ID" },
+ { CSR_MLME_STAKEYESTABLISHED_INDICATION_ID, "CSR_MLME_STAKEYESTABLISHED_INDICATION_ID" },
+ { CSR_MLME_SETPROTECTION_REQUEST_ID, "CSR_MLME_SETPROTECTION_REQUEST_ID" },
+ { CSR_MLME_SETPROTECTION_CONFIRM_ID, "CSR_MLME_SETPROTECTION_CONFIRM_ID" },
+ { CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID, "CSR_MLME_PROTECTEDFRAMEDROPPED_INDICATION_ID" },
+ { CSR_MLME_SNIFFJOIN_REQUEST_ID, "CSR_MLME_SNIFFJOIN_REQUEST_ID" },
+ { CSR_MLME_SNIFFJOIN_CONFIRM_ID, "CSR_MLME_SNIFFJOIN_CONFIRM_ID" },
+ { CSR_MLME_CONNECTED_INDICATION_ID, "CSR_MLME_CONNECTED_INDICATION_ID" },
+ { CSR_MLME_SCAN_CANCEL_REQUEST_ID, "CSR_MLME_SCAN_CANCEL_REQUEST_ID" },
+ { CSR_MLME_NEIGHBORREPREQ_REQUEST_ID, "CSR_MLME_NEIGHBORREPREQ_REQUEST_ID" },
+ { CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID, "CSR_MLME_NEIGHBORREPREQ_CONFIRM_ID" },
+ { CSR_MLME_NEIGHBORREPRESP_INDICATION_ID, "CSR_MLME_NEIGHBORREPRESP_INDICATION_ID" },
+ { CSR_MLME_NEIGHBORREPREQ_INDICATION_ID, "CSR_MLME_NEIGHBORREPREQ_INDICATION_ID" },
+ { CSR_MLME_LINKMEASURE_REQUEST_ID, "CSR_MLME_LINKMEASURE_REQUEST_ID" },
+ { CSR_MLME_LINKMEASURE_CONFIRM_ID, "CSR_MLME_LINKMEASURE_CONFIRM_ID" },
+ { CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID, "CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID" },
+ { CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID, "CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID" },
+ { CSR_MLME_ADD_PERIODIC_REQUEST_ID, "CSR_MLME_ADD_PERIODIC_REQUEST_ID" },
+ { CSR_MLME_ADD_PERIODIC_CONFIRM_ID, "CSR_MLME_ADD_PERIODIC_CONFIRM_ID" },
+ { CSR_MLME_DEL_PERIODIC_REQUEST_ID, "CSR_MLME_DEL_PERIODIC_REQUEST_ID" },
+ { CSR_MLME_DEL_PERIODIC_CONFIRM_ID, "CSR_MLME_DEL_PERIODIC_CONFIRM_ID" },
+ { CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID, "CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID" },
+ { CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID, "CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID" },
+ { CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID, "CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID" },
+ { CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID, "CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID" },
+ { CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID, "CSR_MLME_AUTONOMOUS_SCAN_INDICATION_ID" },
+ { CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID, "CSR_MLME_AUTONOMOUS_SCAN_RESULTS_REQUEST_ID" },
+ { CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID, "CSR_MLME_AUTONOMOUS_SCAN_RESULTS_CONFIRM_ID" },
+ { CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID, "CSR_MLME_AUTONOMOUS_SCAN_RESULTS_INDICATION_ID" },
+ { CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID, "CSR_MLME_SET_UNITDATA_FILTER_REQUEST_ID" },
+ { CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID, "CSR_MLME_SET_UNITDATA_FILTER_CONFIRM_ID" },
+
+ /* 0x04xx */
+ { CSR_DS_UNITDATA_REQUEST_ID, "CSR_DS_UNITDATA_REQUEST_ID" },
+ { CSR_DS_UNITDATA_INDICATION_ID, "CSR_DS_UNITDATA_INDICATION_ID" },
+
+ /* 0x08xx */
+ { CSR_DEBUG_STRING_INDICATION_ID, "CSR_DEBUG_STRING_INDICATION_ID" },
+ { CSR_DEBUG_WORD16_INDICATION_ID, "CSR_DEBUG_WORD16_INDICATION_ID" },
+ { CSR_DEBUG_GENERIC_REQUEST_ID, "CSR_DEBUG_GENERIC_REQUEST_ID" },
+ { CSR_DEBUG_GENERIC_CONFIRM_ID, "CSR_DEBUG_GENERIC_CONFIRM_ID" },
+ { CSR_DEBUG_GENERIC_INDICATION_ID, "CSR_DEBUG_GENERIC_INDICATION_ID" },
+ { 0, NULL }
+};
+
+static const char *
+lookup_something(const struct sig_name *n, int id)
+{
+ for (; n->name; n++) {
+ if (n->id == id) {
+ return n->name;
+ }
+ }
+
+ /* not found */
+ return NULL;
+} /* lookup_something() */
+
+
+const char *
+lookup_signal_name(int id)
+{
+ return lookup_something(Unifi_signal_names, id);
+}
+
+
+static const struct sig_name Unifi_bulkcmd_names[] = {
+ { 0, "SignalCmd" },
+ { 1, "CopyToHost" },
+ { 2, "CopyToHostAck" },
+ { 3, "CopyFromHost" },
+ { 4, "CopyFromHostAck" } ,
+ { 5, "ClearSlot" },
+ { 6, "CopyOverlay" },
+ { 7, "CopyOverlayAck" },
+ { 8, "CopyFromHostAndClearSlot" },
+ { 15, "Padding" },
+ { -1, NULL }
+};
+
+
+const char *
+lookup_bulkcmd_name(int id)
+{
+ return lookup_something(Unifi_bulkcmd_names, id);
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/unifihw.h b/unifi_hostsw_linux_147/unifi-linux/lib_hip/unifihw.h
new file mode 100644
index 0000000..db3d55f
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/unifihw.h
@@ -0,0 +1,62 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * File: unifihw.h
+ *
+ * Definitions of various chip registers, addresses, values etc.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __UNIFIHW_H__
+#define __UNIFIHW_H__ 1
+
+
+/* Symbol Look Up Table fingerprint. IDs are in sigs.h */
+#define SLUT_FINGERPRINT 0xD397
+
+
+/* Values for DBG_HOST_PROC_SELECT */
+#define UNIFI_PROC_MAC 0
+#define UNIFI_PROC_PHY 1
+#define UNIFI_PROC_BT 2
+#define UNIFI_PROC_BOTH 3
+
+
+/* Values of LoaderOperation */
+#define UNIFI_LOADER_IDLE 0x00
+#define UNIFI_LOADER_COPY 0x01
+#define UNIFI_LOADER_ERROR_MASK 0xF0
+
+/* Values of BootLoaderOperation */
+#define UNIFI_BOOT_LOADER_IDLE 0x00
+#define UNIFI_BOOT_LOADER_RESTART 0x01
+#define UNIFI_BOOT_LOADER_PATCH 0x02
+#define UNIFI_BOOT_LOADER_LOAD_STA 0x10
+#define UNIFI_BOOT_LOADER_LOAD_PTEST 0x11
+
+
+/* Memory spaces encoded in top byte of Generic Pointer type */
+#define UNIFI_SH_DMEM 0x01 /* Shared Data Memory */
+#define UNIFI_EXT_FLASH 0x02 /* External FLASH */
+#define UNIFI_EXT_SRAM 0x03 /* External SRAM */
+#define UNIFI_REGISTERS 0x04 /* Registers */
+#define UNIFI_PHY_DMEM 0x10 /* PHY Data Memory */
+#define UNIFI_PHY_PMEM 0x11 /* PHY Program Memory */
+#define UNIFI_PHY_ROM 0x12 /* PHY ROM */
+#define UNIFI_MAC_DMEM 0x20 /* MAC Data Memory */
+#define UNIFI_MAC_PMEM 0x21 /* MAC Program Memory */
+#define UNIFI_MAC_ROM 0x22 /* MAC ROM */
+#define UNIFI_BT_DMEM 0x30 /* BT Data Memory */
+#define UNIFI_BT_PMEM 0x31 /* BT Program Memory */
+#define UNIFI_BT_ROM 0x32 /* BT ROM */
+
+#define UNIFI_MAKE_GP(R, O) (((UNIFI_ ## R) << 24) | (O))
+#define UNIFI_GP_OFFSET(GP) ((GP) & 0xFFFFFF)
+#define UNIFI_GP_SPACE(GP) (((GP) >> 24) & 0xFF)
+
+#endif /* __UNIFIHW_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.c b/unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.c
new file mode 100644
index 0000000..630943b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.c
@@ -0,0 +1,715 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: download.c
+ *
+ * PURPOSE:
+ * Routines for downloading firmware to UniFi.
+ *
+ * UniFi firmware files use a nested TLV (Tag-Length-Value) format.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifdef TEST
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <limits.h>
+#include "driver/signals.h"
+#include "unifihw.h"
+void unifi_error(void* ospriv, const char *fmt, ...);
+struct card {
+ void *ospriv;
+};
+typedef struct card card_t;
+#else
+#include "driver/unifiversion.h"
+#include "card.h"
+#endif /* TEST */
+#include "xbv.h"
+
+
+/* Struct to represent a buffer for reading firmware file */
+
+typedef struct {
+ void *dlpriv;
+ int ioffset;
+ fwreadfn_t iread;
+} ct_t;
+
+/* Struct to represent a TLV field */
+typedef struct {
+ char t_name[4];
+ int t_len;
+} tag_t;
+
+
+#define TAG_EQ(i, v) (((i)[0] == (v)[0]) && \
+ ((i)[1] == (v)[1]) && \
+ ((i)[2] == (v)[2]) && \
+ ((i)[3] == (v)[3]))
+
+/* We create a small stack on the stack that contains an enum
+ * indicating the containing list segments, and the offset at which
+ * those lists end. This enables a lot more error checking. */
+typedef enum
+{
+ xbv_xbv1,
+ /*xbv_info,*/
+ xbv_fw,
+ xbv_vers,
+ xbv_vand,
+ xbv_ptch,
+ xbv_other
+} xbv_container;
+
+#define XBV_STACK_SIZE 6
+
+typedef struct
+{
+ struct
+ {
+ xbv_container container;
+ int ioffset_end;
+ } s[XBV_STACK_SIZE];
+ int ptr;
+} xbv_stack_t;
+
+static int read_tag(card_t *card, ct_t *ct, tag_t *tag);
+static int read_bytes(card_t *card, ct_t *ct, void *buf, int len);
+static int read_uint(card_t *card, ct_t *ct, unsigned int *u, int len);
+static int xbv_check(xbv1_t *fwinfo, const xbv_stack_t *stack,
+ xbv_mode new_mode, xbv_container old_cont);
+static int xbv_push(xbv1_t *fwinfo, xbv_stack_t *stack,
+ xbv_mode new_mode, xbv_container old_cont,
+ xbv_container new_cont, int ioff);
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * parse_xbv1
+ *
+ * Scan the firmware file to find the TLVs we are interested in.
+ * Actions performed:
+ * - check we support the file format version in VERF
+ * Store these TLVs if we have a firmware image:
+ * - SLTP Symbol Lookup Table Pointer
+ * - FWDL firmware download segments
+ * - FWOL firmware overlay segment
+ * - VMEQ Register probe tests to verify matching h/w
+ * Store these TLVs if we have a patch file:
+ * - FWID the firmware build ID that this file patches
+ * - PTDL The actual patches
+ *
+ * The structure pointed to by fwinfo is cleared and
+ * 'fwinfo->mode' is set to 'unknown'. The 'fwinfo->mode'
+ * variable is set to 'firmware' or 'patch' once we know which
+ * sort of XBV file we have.
+ *
+ * Arguments:
+ * readfn Pointer to function to call to read from the file.
+ * dlpriv Opaque pointer arg to pass to readfn.
+ * fwinfo Pointer to fwinfo struct to fill in.
+ *
+ * Returns:
+ * 0 on success, -1 on error.
+ * ---------------------------------------------------------------------------
+ */
+int
+xbv1_parse(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo)
+{
+ ct_t ct;
+ tag_t tag;
+ xbv_stack_t stack;
+
+ ct.dlpriv = dlpriv;
+ ct.ioffset = 0;
+ ct.iread = readfn;
+
+ memset(fwinfo, 0, sizeof(xbv1_t));
+ fwinfo->mode = xbv_unknown;
+
+ /* File must start with XBV1 triplet */
+ if (read_tag(card, &ct, &tag) <= 0) {
+ return -1;
+ }
+
+ if (!TAG_EQ(tag.t_name, "XBV1")) {
+ unifi_error(NULL, "File is not UniFi firmware\n");
+ return -1;
+ }
+
+ stack.ptr = 0;
+ stack.s[stack.ptr].container = xbv_xbv1;
+ stack.s[stack.ptr].ioffset_end = INT_MAX;
+
+ /* Now scan the file */
+ while (1) {
+ int n;
+
+ n = read_tag(card, &ct, &tag);
+ if (n < 0) {
+ return -1;
+ }
+ if (n == 0) {
+ /* End of file */
+ break;
+ }
+
+ /* File format version */
+ if (TAG_EQ(tag.t_name, "VERF")) {
+ unsigned int version;
+
+ if (xbv_check(fwinfo, &stack, xbv_unknown, xbv_xbv1) ||
+ (tag.t_len != 2) ||
+ read_uint(card, &ct, &version, 2)) {
+ return -1;
+ }
+ if (version != 0) {
+ unifi_error(NULL, "Unsupported firmware file version: %d.%d\n",
+ version >> 8, version & 0xFF);
+ return -1;
+ }
+ }
+ else if (TAG_EQ(tag.t_name, "LIST"))
+ {
+ char name[4];
+ int list_end;
+
+ list_end = ct.ioffset + tag.t_len;
+
+ if (read_bytes(card, &ct, name, 4))
+ return -1;
+
+ if (TAG_EQ(name, "FW "))
+ {
+ if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_xbv1, xbv_fw, list_end))
+ return -1;
+ }
+ else if (TAG_EQ(name, "VERS"))
+ {
+ if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_fw, xbv_vers, list_end) ||
+ (fwinfo->vers.num_vand != 0))
+ return -1;
+ }
+ else if (TAG_EQ(name, "VAND"))
+ {
+ struct VAND *vand;
+
+ if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_vers, xbv_vand, list_end) ||
+ (fwinfo->vers.num_vand >= MAX_VAND))
+ return -1;
+
+ /* Get a new VAND */
+ vand = fwinfo->vand + fwinfo->vers.num_vand++;
+
+ /* Fill it in */
+ vand->first = fwinfo->num_vmeq;
+ vand->count = 0;
+ }
+ else if (TAG_EQ(name, "PTCH"))
+ {
+ if (xbv_push(fwinfo, &stack, xbv_patch, xbv_xbv1, xbv_ptch, list_end))
+ return -1;
+ }
+ else
+ {
+ /* Skip over any other lists. We dont bother to push
+ * the new list type now as we would only pop it at
+ * the end of the outer loop. */
+ ct.ioffset += tag.t_len - 4;
+ }
+ }
+ else if (TAG_EQ(tag.t_name, "SLTP"))
+ {
+ unsigned int addr;
+
+ if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) ||
+ (tag.t_len != 4) ||
+ (fwinfo->slut_addr != 0) ||
+ read_uint(card, &ct, &addr, 4)) {
+ return -1;
+ }
+
+ fwinfo->slut_addr = addr;
+ }
+ else if (TAG_EQ(tag.t_name, "FWDL"))
+ {
+ unsigned int addr;
+ struct FWDL *fwdl;
+
+ if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) ||
+ (fwinfo->num_fwdl >= MAX_FWDL) ||
+ (read_uint(card, &ct, &addr, 4))) {
+ return -1;
+ }
+
+ fwdl = fwinfo->fwdl + fwinfo->num_fwdl++;
+
+ fwdl->dl_size = tag.t_len - 4;
+ fwdl->dl_addr = addr;
+ fwdl->dl_offset = ct.ioffset;
+
+ ct.ioffset += tag.t_len - 4;
+ }
+ else if (TAG_EQ(tag.t_name, "FWOV"))
+ {
+ if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) ||
+ (fwinfo->fwov.dl_size != 0) ||
+ (fwinfo->fwov.dl_offset != 0)) {
+ return -1;
+ }
+
+ fwinfo->fwov.dl_size = tag.t_len;
+ fwinfo->fwov.dl_offset = ct.ioffset;
+
+ ct.ioffset += tag.t_len;
+ }
+ else if (TAG_EQ(tag.t_name, "VMEQ"))
+ {
+ unsigned int temp[3];
+ struct VAND *vand;
+ struct VMEQ *vmeq;
+
+ if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_vand) ||
+ (fwinfo->num_vmeq >= MAX_VMEQ) ||
+ (fwinfo->vers.num_vand == 0) ||
+ (tag.t_len != 8) ||
+ read_uint(card, &ct, &temp[0], 4) ||
+ read_uint(card, &ct, &temp[1], 2) ||
+ read_uint(card, &ct, &temp[2], 2)) {
+ return -1;
+ }
+
+ /* Get the last VAND */
+ vand = fwinfo->vand + (fwinfo->vers.num_vand - 1);
+
+ /* Get a new VMEQ */
+ vmeq = fwinfo->vmeq + fwinfo->num_vmeq++;
+
+ /* Note that this VAND contains another VMEQ */
+ vand->count++;
+
+ /* Fill in the VMEQ */
+ vmeq->addr = temp[0];
+ vmeq->mask = (uint16)temp[1];
+ vmeq->value = (uint16)temp[2];
+ }
+ else if (TAG_EQ(tag.t_name, "FWID"))
+ {
+ unsigned int build_id;
+
+ if (xbv_check(fwinfo, &stack, xbv_patch, xbv_ptch) ||
+ (tag.t_len != 4) ||
+ (fwinfo->build_id != 0) ||
+ read_uint(card, &ct, &build_id, 4))
+ return -1;
+
+ fwinfo->build_id = build_id;
+ }
+ else if (TAG_EQ(tag.t_name, "PTDL"))
+ {
+ struct PTDL *ptdl;
+
+ if (xbv_check(fwinfo, &stack, xbv_patch, xbv_ptch) ||
+ (fwinfo->num_ptdl >= MAX_PTDL))
+ return -1;
+
+ /* Allocate a new PTDL */
+ ptdl = fwinfo->ptdl + fwinfo->num_ptdl++;
+
+ ptdl->dl_size = tag.t_len;
+ ptdl->dl_offset = ct.ioffset;
+
+ ct.ioffset += tag.t_len;
+ }
+ else
+ {
+ /*
+ * If we get here it is a tag we are not interested in,
+ * just skip over it.
+ */
+ ct.ioffset += tag.t_len;
+ }
+
+ /* Check to see if we are at the end of the currently stacked
+ * segment. We could finish more than one list at a time. */
+ while (ct.ioffset >= stack.s[stack.ptr].ioffset_end) {
+ if (ct.ioffset > stack.s[stack.ptr].ioffset_end) {
+ unifi_error(NULL, "XBV file has overrun stack'd segment\n");
+ return -1;
+ }
+ if (stack.ptr <= 0) {
+ unifi_error(NULL, "XBV file has underrun stack pointer\n");
+ return -1;
+ }
+ stack.ptr--;
+ }
+ }
+
+ if (stack.ptr != 0) {
+ unifi_error(NULL, "Last list of XBV is not complete.\n");
+ return -1;
+ }
+
+ return 0;
+} /* xbv1_parse() */
+
+
+/* Check the the XBV file is of a consistant sort (either firmware or
+ * patch) and that we are in the correct containing list type. */
+static int xbv_check(xbv1_t *fwinfo, const xbv_stack_t *stack,
+ xbv_mode new_mode, xbv_container old_cont)
+{
+ /* If the new file mode is unknown the current packet could be in
+ * either (any) type of XBV file, and we cant make a decission at
+ * this time. */
+ if (new_mode != xbv_unknown) {
+ if (fwinfo->mode == xbv_unknown) {
+ fwinfo->mode = new_mode;
+ } else if (fwinfo->mode != new_mode) {
+ return -1;
+ }
+ }
+ /* If the current stack top doesn't match what we expect then the
+ * file is corrupt. */
+ if (stack->s[stack->ptr].container != old_cont) {
+ return -1;
+ }
+ return 0;
+}
+
+/* Make checks as above and then enter a new list */
+static int xbv_push(xbv1_t *fwinfo, xbv_stack_t *stack,
+ xbv_mode new_mode, xbv_container old_cont,
+ xbv_container new_cont, int new_ioff)
+{
+ if (xbv_check(fwinfo, stack, new_mode, old_cont)) {
+ return -1;
+ }
+
+ /* Check that our stack won't overflow. */
+ if (stack->ptr >= (XBV_STACK_SIZE - 1))
+ return -1;
+
+ /* Add the new list element to the top of the stack. */
+ stack->ptr++;
+ stack->s[stack->ptr].container = new_cont;
+ stack->s[stack->ptr].ioffset_end = new_ioff;
+
+ return 0;
+}
+
+
+static unsigned int
+xbv2uint(unsigned char *ptr, int len)
+{
+ unsigned int u = 0;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ unsigned int b;
+ b = ptr[i];
+ u += b << (i * 8);
+ }
+ return u;
+}
+
+
+
+static int
+read_tag(card_t *card, ct_t *ct, tag_t *tag)
+{
+ unsigned char buf[8];
+ int n;
+
+ n = (*ct->iread)(card->ospriv, ct->dlpriv, ct->ioffset, buf, 8);
+ if (n <= 0) {
+ return n;
+ }
+
+ /* read the tag and length */
+ if (n != 8) {
+ return -1;
+ }
+
+ /* get section tag */
+ memcpy(tag->t_name, buf, 4);
+
+ /* get section length */
+ tag->t_len = xbv2uint(buf+4, 4);
+
+ ct->ioffset += 8;
+
+ return 8;
+} /* read_tag() */
+
+
+static int
+read_bytes(card_t *card, ct_t *ct, void *buf, int len)
+{
+ /* read the tag value */
+ if ((*ct->iread)(card->ospriv, ct->dlpriv, ct->ioffset, buf, len) != len) {
+ return -1;
+ }
+
+ ct->ioffset += len;
+
+ return 0;
+} /* read_bytes() */
+
+static int
+read_uint(card_t *card, ct_t *ct, unsigned int *u, int len)
+{
+ unsigned char buf[4];
+
+ /* Integer cannot be more than 4 bytes */
+ if (len > 4) {
+ return -1;
+ }
+
+ if (read_bytes(card, ct, buf, len)) return -1;
+
+ *u = xbv2uint(buf, len);
+
+ return 0;
+} /* read_uint() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_slut
+ *
+ * desc
+ *
+ * Arguments:
+ * readfn Pointer to function to call to read from the file.
+ * dlpriv Opaque pointer arg to pass to readfn.
+ * addr Offset into firmware image of SLUT.
+ * fwinfo Pointer to fwinfo struct to fill in.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int
+xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo,
+ symbol_t *slut, int slut_len)
+{
+ int i;
+ int offset;
+ unsigned int magic;
+ int count = 0;
+ ct_t ct;
+
+ if (fwinfo->mode != xbv_firmware) {
+ return -1;
+ }
+
+ /* Find the d/l segment containing the SLUT */
+ /* This relies on the SLUT being entirely contained in one segment */
+ offset = -1;
+ for (i = 0; i < fwinfo->num_fwdl; i++)
+ {
+ if ((fwinfo->slut_addr >= fwinfo->fwdl[i].dl_addr) &&
+ (fwinfo->slut_addr < (fwinfo->fwdl[i].dl_addr + fwinfo->fwdl[i].dl_size)))
+ {
+ offset = fwinfo->fwdl[i].dl_offset +
+ (fwinfo->slut_addr - fwinfo->fwdl[i].dl_addr);
+ }
+ }
+ if (offset < 0) {
+ return -1;
+ }
+
+ ct.dlpriv = dlpriv;
+ ct.ioffset = offset;
+ ct.iread = readfn;
+
+ if (read_uint(card, &ct, &magic, 2)) return -1;
+ if (magic != SLUT_FINGERPRINT) {
+ return -1;
+ }
+
+ while (count < slut_len) {
+ unsigned int id, obj;
+
+ /* Read Symbol Id */
+ if (read_uint(card, &ct, &id, 2)) return -1;
+
+ /* Check for end of table marker */
+ if (id == CSR_SLT_END) {
+ break;
+ }
+
+ /* Read Symbol Value */
+ if (read_uint(card, &ct, &obj, 4)) return -1;
+
+ slut[count].id = (uint16)id;
+ slut[count].obj = obj;
+ count++;
+ }
+
+ return count;
+
+} /* read_slut() */
+
+
+#ifdef TEST
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * This file will compile with -DTEST.
+ * The resulting executable will scan and print out the f/w info derived from
+ * test.xbv.
+ *
+ * ---------------------------------------------------------------------------
+ */
+struct img {
+ unsigned char *imgptr;
+ int imglen;
+};
+
+static int
+rfn(void* ospriv, void *dlpriv, int offset, void *buf, int len)
+{
+ struct img *img = dlpriv;
+
+
+ if (offset == img->imglen) {
+ /* at end of file */
+ return 0;
+ }
+
+ if ((offset+len) > img->imglen) {
+ /* attempt to read past end of file */
+ return -1;
+ }
+
+ memcpy(buf, img->imgptr+offset, len);
+
+ return len;
+}
+
+void unifi_error(void* ospriv, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *filename = "test.xbv";
+ FILE *fp;
+ unsigned char *buf;
+ int i, j, n;
+ ct_t ct;
+ struct img img;
+ xbv1_t fwinfo;
+#define MAX_SLUT_ENTRIES 32
+ symbol_t slut[MAX_SLUT_ENTRIES];
+ int num_slut_entries;
+ struct card card;
+
+ if (argc > 1) {
+ filename = argv[1];
+ }
+
+ buf = malloc(256*1024);
+
+ fp = fopen(filename, "r");
+ if (!fp) {
+ perror("Failed to open test.xbv");
+ exit(errno);
+ }
+ n = fread(buf, 1, 256*1024, fp);
+ if (n < 0) {
+ perror("Failed to read test.xbv");
+ exit(errno);
+ }
+
+
+ memset(&fwinfo, 0, sizeof(fwinfo));
+
+ img.imgptr = buf;
+ img.imglen = n;
+
+ n = xbv1_parse(&card, rfn, &img, &fwinfo);
+ if (n) {
+ printf("Parse failed\n");
+ exit(1);
+ }
+
+ switch (fwinfo.mode)
+ {
+ case xbv_firmware:
+ printf("XBV File contains a firmware image.\n");
+ num_slut_entries = xbv1_read_slut(&card, rfn, &img, &fwinfo, slut, MAX_SLUT_ENTRIES);
+
+ if (fwinfo.vers.num_vand != 0) {
+ printf(" VERS: for %d\n", fwinfo.vers.num_vand);
+
+ for (i = 0; i < fwinfo.vers.num_vand; i++) {
+ printf(" VAND: %d for %d\n",
+ fwinfo.vand[i].first, fwinfo.vand[i].count);
+
+ for (j = 0; j < fwinfo.vand[i].count; j++) {
+ int k = fwinfo.vand[i].first + j;
+ printf(" VMEQ: *0x%08lx & 0x%04X == 0x%04X\n",
+ fwinfo.vmeq[k].addr, fwinfo.vmeq[k].mask, fwinfo.vmeq[k].value);
+ }
+ }
+ }
+
+ printf("SLUT addr 0x%X\n", fwinfo.slut_addr);
+ printf("%d SLUT entr%s:\n", num_slut_entries, (num_slut_entries == 1) ? "y" : "ies");
+ for (i = 0; i < num_slut_entries; i++) {
+ printf(" SLUT: 0x%04X, 0x%08X\n",
+ slut[i].id, slut[i].obj);
+ }
+
+ printf("%d F/W segment%s\n", fwinfo.num_fwdl, (fwinfo.num_fwdl == 1) ? "" : "s");
+ for (i = 0; i < fwinfo.num_fwdl; i++) {
+ printf(" FWDL: dest 0x%08lx, len %6d, file offset 0x%X\n",
+ fwinfo.fwdl[i].dl_addr, fwinfo.fwdl[i].dl_size,
+ fwinfo.fwdl[i].dl_offset);
+ }
+
+ if (fwinfo.fwov.dl_size > 0) {
+ printf("Overlay segment\n");
+ printf(" FWOV: len %6d, file offset 0x%X\n",
+ fwinfo.fwov.dl_size, fwinfo.fwov.dl_offset);
+ } else {
+ printf("No overlay segment\n");
+ }
+ break;
+
+ case xbv_patch:
+ printf("XBV File contains a patch set.\n");
+
+ printf("FWID build id %u\n", fwinfo.build_id);
+
+ printf("%d Patch segment%s\n", fwinfo.num_ptdl, (fwinfo.num_ptdl == 1) ? "" : "s");
+ for (i = 0; i < fwinfo.num_ptdl; i++) {
+ printf(" PTDL: len %5d, file offset 0x%X\n",
+ fwinfo.ptdl[i].dl_size, fwinfo.ptdl[i].dl_offset);
+ }
+ break;
+
+ default:
+ printf("XBV File seems to be corrupt.\n");
+ break;
+ }
+}
+
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.h b/unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.h
new file mode 100644
index 0000000..8456c45
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_hip/xbv.h
@@ -0,0 +1,108 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: xbv.h
+ *
+ * PURPOSE:
+ * Definitions and declarations for code to read XBV files - the UniFi
+ * firmware download file format.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __XBV_H__
+#define __XBV_H__
+
+#ifndef TEST
+#include "driver/unifi.h"
+#endif
+
+
+struct VMEQ {
+ unsigned long addr;
+ uint16 mask;
+ uint16 value;
+};
+
+struct VAND {
+ unsigned int first;
+ unsigned int count;
+};
+
+struct VERS {
+ unsigned int num_vand;
+};
+
+struct FWDL {
+ unsigned long dl_addr;
+ unsigned int dl_size;
+ unsigned int dl_offset;
+};
+
+struct FWOV {
+ unsigned int dl_size;
+ unsigned int dl_offset;
+};
+
+struct PTDL {
+ unsigned int dl_size;
+ unsigned int dl_offset;
+};
+
+#define MAX_VMEQ 64
+#define MAX_VAND 64
+#define MAX_FWDL 256
+#define MAX_PTDL 256
+
+/* An XBV1 file can either contain firmware or patches (at the
+ * moment). The 'mode' member of the xbv1_t structure tells us which
+ * one is the case. */
+typedef enum
+{
+ xbv_unknown,
+ xbv_firmware,
+ xbv_patch
+} xbv_mode;
+
+typedef struct {
+
+ xbv_mode mode;
+
+ /* Parts of a Firmware XBV1 */
+
+ struct VMEQ vmeq[MAX_VMEQ];
+ unsigned int num_vmeq;
+ struct VAND vand[MAX_VAND];
+ struct VERS vers;
+
+ unsigned long slut_addr;
+
+ /* F/W download image, possibly more than one part */
+ struct FWDL fwdl[MAX_FWDL];
+ int num_fwdl;
+
+ /* F/W overlay image, add r not used */
+ struct FWOV fwov;
+
+ /* Parts of a Patch XBV1 */
+
+ unsigned long build_id;
+
+ struct PTDL ptdl[MAX_PTDL];
+ int num_ptdl;
+
+} xbv1_t;
+
+
+typedef int (*fwreadfn_t)(void *ospriv, void *dlpriv, int offset, void *buf, int len);
+
+int xbv1_parse(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo);
+int xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo,
+ symbol_t *slut, int slut_len);
+
+
+
+#endif /* __XBV_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/abstractions/osa.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/abstractions/osa.h
new file mode 100644
index 0000000..d65d099
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/abstractions/osa.h
@@ -0,0 +1,534 @@
+/** @file osa.h
+ *
+ * Operating System Abstraction main header file
+ *
+ * @section LEGAL
+ * CONFIDENTIAL
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source for details on the
+ * license terms.
+ *
+ * @section DESCRIPTION
+ * Provides abstraction API for typical OS-related functions such as
+ * malloc, free, etc.
+ *
+ ****************************************************************************
+ *
+ * @section REVISION
+ * $Id: //depot/dot11/v6.1/host/lib_sme/common/abstractions/osa.h#1 $
+ *
+ ****************************************************************************/
+#ifndef OSA_H
+# define OSA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @{
+ * @ingroup abstractions
+ */
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* PROJECT INCLUDES *********************************************************/
+#include "osa_types.h"
+
+/* PUBLIC MACROS ************************************************************/
+/**
+ * This macro defines the behaviour of the system under a panic condition.
+ * There are two available options: osa_panic_verbose and osa_panic_brief,
+ * both of which are documented below.
+ */
+#define osa_panic(rc) osa_panic_verbose(__FILE__, __LINE__, (rc))
+/*#define osa_panic(rc) osa_panic_brief(rc)*/
+
+/**
+ * This macro defines the number of milliseconds in a second
+ */
+#define MS_SEC (1000)
+
+/**
+ * This macro defines the number of microseconds in a second
+ */
+#define US_SEC ((1000 * 1000)UL)
+
+
+/* PUBLIC TYPES DEFINITIONS *************************************************/
+/**
+ * @brief
+ * A panic reason code
+ *
+ * @par Description
+ * This provides the upper layers with a set of reason codes to use when
+ * calling the osa_panic function.
+ */
+typedef enum
+{
+ /** Memory exhaustion */
+ OSA_PANIC_MEM_EXHAUST,
+ /** Unable to initialise the osa */
+ OSA_PANIC_OSA_INIT,
+ /** Error marking start of critical section code */
+ OSA_PANIC_CRITSEC_ENTRY,
+ /** Error marking end of critical section code */
+ OSA_PANIC_CRITSEC_EXIT,
+ /** Panic unsupported operation occured */
+ OSA_PANIC_UNSUPPORTED,
+ /** Error in signal unpacking engine */
+ OSA_PANIC_PACK_ERROR,
+ /** Error in signal packing engine */
+ OSA_PANIC_UNPACK_ERROR,
+ /** Internal logic failure */
+ OSA_PANIC_INTERNAL_LOGIC,
+ /** Unknown or unspecified panic reason */
+ OSA_PANIC_UNKNOWN
+} osa_panic_code;
+
+typedef struct OsaMutex OsaMutex;
+
+/* PUBLIC CONSTANT DECLARATIONS *********************************************/
+
+/* PUBLIC VARIABLE DECLARATIONS *********************************************/
+
+/* PUBLIC FUNCTION PROTOTYPES ***********************************************/
+
+/**
+ * @brief
+ * Initialises the osa
+ *
+ * @par Description
+ * Initialises and Data needed by the osa for use
+ * This function should only be called ONCE before any other osa functions are
+ * called.
+ *
+ * @return
+ * void
+ *
+ * @remarks
+ * Calls osa_panic on any failure
+ * @par
+ * The exact specification of the requirements for this function depend on
+ * the threading model used on the target platform. Please refer to the SME
+ * Porting guide for full details.
+ *
+ * @par
+ * See also osa_shutdown().
+ */
+extern void osa_initialise(void);
+
+/**
+ * @brief
+ * Frees any resources allocated by osa_initialise
+ *
+ * @par Description
+ * This function is called ONCE prior to complete termination of the
+ * program. It should free any resources allocated by osa_initialise.
+ *
+ * @return
+ * void
+ *
+ * @remarks
+ * Failures must not cause this function to terminate prematurely; it
+ * should attempt to free any resources owned by osa_initialise.
+ * @par
+ * The exact specification of the requirements for this function depend on
+ * the threading model used on the target platform. Please refer to the SME
+ * Porting guide for full details.
+ */
+extern void osa_shutdown(void);
+
+/**
+ * @brief
+ * Abnormal program termination mechanism with verbose 'output'
+ *
+ * @par Description
+ * Allows software to cause an abnormal program termination, possibly
+ * resulting in a hardware reset or service-affecting recovery
+ * mechanism. It should be called whenever a critical error that cannot
+ * be handled by normal (software) mechanisms occurs, for example a
+ * failure to obtain heap resources.
+ * @par
+ * This function does not return control to the calling context but when
+ * feasable the panic code passed via argument 3 is exported to the executive
+ * environment under which the SME was spawned by calling, for example,
+ * exit(reason).
+ * @par
+ * Either this function or osa_panic_brief() will be mapped to be the
+ * expansion for the osa_panic macro. The implementation provided by this
+ * function attempts to output (via sme_trace) the source file name and
+ * line number where the osa_panic macro was invoked in addition to the
+ * panic code (reason).
+ *
+ * @param[in] filename : The name of the file where panic was called
+ * @param[in] lineNum : The line in the file where panic was called
+ * @param[in] reason : The reason for the panic (panicCode type)
+ *
+ * @return
+ * NONE - this function never returns
+ *
+ * @remarks
+ * osa_panic will be macro'd to either this function or osa_panic_brief
+ */
+extern void osa_panic_verbose(const char * filename,
+ int lineNum,
+ osa_panic_code reason) OSA_NORETURN;
+
+/**
+ * @brief
+ * Abnormal program termination mechanism with brief 'output'
+ *
+ * @par Description
+ * Allows software to cause an abnormal program termination, possibly
+ * resulting in a hardware reset or service-affecting recovery
+ * mechanism. It should be called whenever a critical error that cannot
+ * be handled by normal (software) mechanisms occurs, for example a
+ * failure to obtain heap resources.
+ * @par
+ * This function does not return control to the calling context but when
+ * feasable the panic code passed via argument 3 is exported to the executive
+ * environment under which the SME was spawned by calling, for example,
+ * exit(reason).
+ * @par
+ * Either this function or osa_panic_verbose() will be mapped to be the
+ * expansion for the osa_panic macro. The implementation provided by this
+ * function attempts to output (via sme_trace) the panic code (reason).
+ *
+ * @param[in] reason : The reason for the panic (panicCode type)
+ *
+ * @return
+ * NONE - this function never returns
+ *
+ * @remarks
+ * osa_panic will be macro'd to either this function or osa_panic_verbose
+ */
+extern void osa_panic_brief(osa_panic_code reason) OSA_NORETURN;
+
+/**
+ * @brief
+ * malloc() abstraction
+ *
+ * @par Description
+ * This function, like its ANSI C Library malloc() equivalent, allocates sz
+ * bytes of contiguous memory and returns a pointer to the start of the
+ * allocated memory. The memory is not required to be cleared.
+ * @par
+ * Additionally, osa_malloc() needs to record the length of the block
+ * associated with the returned address so that any calls to osa_msizeof()
+ * function are correctly serviced.
+ *
+ * @param[in] sz : The amount of memory to allocate in bytes
+ *
+ * @return
+ * void *: pointer to the allocated memory block
+ *
+ * @remarks
+ * Unlike malloc() if the allocation request cannot be satisfied, this
+ * function calls osa_panic() with an osa_panic_code of OSA_PANIC_MEM_EXHAUST.
+ * A NULL pointer is never returned.
+ *
+ * @pre sz > 0
+ *
+ * @post
+ * returns pointer to contiguous block of memory of at least size (sz) bytes
+ */
+#define osa_malloc(sz) malloc(sz)
+
+/**
+ * @brief
+ * calloc() abstraction
+ *
+ * @par Description
+ * This function, like its ANSI C Library calloc() equivalent, behaves similarly
+ * to the osa_malloc() function, except that the size of the memory block is given
+ * by (nmemb sz) where nmemb is the number of members and that the allocated block
+ * has its content cleared (initialised to zero).
+ *
+ * @param[in] nmemb : Number of members (units) to allocate
+ * @param[out] sz : The size of each member in bytes
+ *
+ * @return
+ * void *: pointer to the allocated memory block
+ *
+ * @see osa_malloc
+ *
+ * @remarks
+ * Like osa_malloc, a failure to perform the allocation request, results in
+ * this function calling osa_panic() with an osa_panic_code of
+ * OSA_PANIC_MEM_EXHAUST. A NULL pointer is never returned.
+ * @par
+ * May rely on functionality provided by osa_malloc. If it does not, the
+ * function must ensure that it records the length of the block associated
+ * with the returned address so that any calls to osa_msizeof() are correctly
+ * serviced.
+ *
+ * @pre nmemb > 0
+ * @pre sz > 0
+ *
+ * @post returns pointer to contiguous block of memory of at least size (sz) bytes
+ * whose contents have been initialised to zero.
+ */
+#define osa_calloc(nmemb, sz) calloc(nmemb, sz)
+
+/**
+ * @brief
+ * free() abstraction.
+ *
+ * @par Description
+ * This function, like its ANSI C free() equivalent, releases the memory
+ * referenced by ptr. It assumes that the addresses referenced by ptr was
+ * returned by an earlier call to either osa_malloc(), or osa_calloc().
+ *
+ * @param[in] ptr : Pointer to the mem block that is no longer needed
+ *
+ * @return
+ * void
+ *
+ * @remarks
+ * Calls to osa_free() with ptr containing an address not returned by a
+ * prior call to osa_malloc() or osa_calloc() results in undefined behaviour.
+ * @par
+ * Will accept (ignore) an attempt to free a NULL pointer
+ *
+ * @pre ptr must reference a valid block of memory allocated previously using
+ * osa_malloc or osa_calloc.
+ */
+#define osa_free(ptr) free(ptr)
+
+/**
+ * @brief
+ * Creates a critical section
+ *
+ * @par Description
+ * See brief
+ *
+ * @return
+ * OsaMutex;
+ *
+ * @remarks
+ * Calls osa_panic on any failure
+ */
+extern OsaMutex* osa_critical_section_create(void);
+
+/**
+ * @brief
+ * Marks the begining of a critical section of code at which point no other
+ * execution context may get to run.
+ *
+ * @par Description
+ * See brief
+ *
+ * @return
+ * void
+ *
+ * @remarks
+ * Calls osa_panic on any failure
+ * @par
+ * The exact specification of the requirements for this function depend on
+ * the threading model used on the target platform. Please refer to the SME
+ * Porting guide for full details.
+ *
+ * @pre hdl must be a valid critical section
+ */
+extern void osa_critical_section_entry(OsaMutex* mutex);
+
+/**
+ * @brief
+ * Marks the end of a critical section of code at which point other
+ * execution contexts may be allowed to run the previously protected code.
+ *
+ * @par Description
+ * See brief
+ *
+ * @return
+ * void
+ *
+ * @remarks
+ * Calls osa_panic on any failure
+
+ * @par
+ * The exact specification of the requirements for this function depend on
+ * the threading model used on the target platform. Please refer to the SME
+ * Porting guide for full details.
+ *
+ * @pre hdl must be a valid critical section
+ */
+extern void osa_critical_section_exit(OsaMutex* mutex);
+
+/**
+ * @brief
+ * Destroys a critical section
+ *
+ * @par Description
+ * See brief
+ *
+ * @return
+ * void
+ *
+ * @remarks
+ * Calls osa_panic on any failure
+ */
+extern void osa_critical_section_destroy(OsaMutex* mutex);
+
+/**
+ * @brief
+ * Returns the time of day in milliseconds.
+ *
+ * @par Description
+ * This function returns a representation of 'current time' that is held
+ * in a timer whose value increases in units of milliseconds. This value
+ * wraps through zero across the 32-bit boundary.
+ *
+ * @return
+ * uint32: millisecond resolution timer value
+ *
+ * @remarks
+ * The timer need not have resolution of 1 millisecond, i.e. it may increment
+ * by 'n' every 'n' milliseconds.
+ *
+ * @post The returned value must simulate a timer that increments by 1 every
+ * millisecond and wraps to zero at 2^32.
+ */
+extern uint32 osa_get_time_of_day_milli_seconds(void);
+
+#ifdef SME_TEST_SUPPORT
+/**
+ * @brief
+ * Advances the time of day
+ *
+ * @par Description
+ * This function adds an offset to the time reported by
+ * osa_get_time_of_day_milli_seconds(). The offset is cumulative so
+ * increases with subsequent calls to osa_advance_time().
+ *
+ * @return
+ * void
+ */
+extern void osa_advance_time(uint32 ms);
+#endif
+
+/**
+ * @brief
+ * Populate a buffer with random data
+ *
+ * @par Description
+ * Support
+ */
+extern void osa_random(uint8* buff, uint32 length);
+
+/**
+ * @brief
+ * Compare two strings
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'strncmp'
+ */
+#define osa_strncmp(s1, s2, n) strncmp(s1, s2, n)
+
+/**
+ * @brief
+ * Copy a string into a pre-allocated buffer
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'strcpy'
+ */
+#define osa_strcpy(dest, src) strcpy(dest, src)
+
+/**
+ * @brief
+ * Concatenates a string onto the end of another string in a pre-allocated
+ * buffer
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'strcat'
+ */
+#define osa_strcat(dest, src) strcat(dest, src)
+
+
+/**
+ * @brief
+ * Gives the number of bytes in a string, not including the zero terminator
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'strlen'
+ */
+#define osa_strlen(s) strlen(s)
+
+/**
+ * @brief
+ * Fills an area of memory with the given 8-bit value
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'memset'
+ */
+#define osa_memset(s, c, n) memset(s, c, n)
+
+/**
+ * @brief
+ * Copies an area of memory to a pre-allocated buffer
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'memcpy'
+ */
+#define osa_memcpy(dest, src, n) memcpy(dest, src, n)
+
+/**
+ * @brief
+ * Moves an data from one area of memory to another. The source and
+ * destination areas may overlap.
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'memmove'
+ */
+#define osa_memmove(dest, src, n) memmove(dest, src, n)
+
+/**
+ * @brief
+ * Compare two areas of memory
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'memcmp'
+ */
+#define osa_memcmp(s1, s2, n) memcmp(s1, s2, n)
+
+/**
+ * @brief
+ * Convert a string to an unsigned long value
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'strtoul'
+ */
+#define osa_strtoul(nptr, endptr, base) strtoul(nptr, endptr, base)
+
+/**
+ * @brief
+ * Printf into a string
+ *
+ * @par Description
+ * Provides identical functionality to the ANSI C 'sprintf'
+ */
+#define osa_sprintf sprintf
+
+/**
+ * @brief
+ * assert function
+ *
+ * @par Description
+ * Provides identical functionality to linux <assert.h> 'assert'
+ */
+#define osa_assert assert
+
+
+/* OVERRIDE AND IMPLEMENTATION INCLUDES *********************************************************/
+#include "osa_support.h"
+
+
+/** @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* OSA_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.c b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.c
new file mode 100644
index 0000000..4f8f385
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.c
@@ -0,0 +1,199 @@
+/** @file event_pack_unpack.c
+ *
+ * event Packing and unpacking functions
+ *
+ * @section LEGAL
+ * CONFIDENTIAL
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source for details on the
+ * license terms.
+ *
+ * @section DESCRIPTION
+ * Implements Event Packing and Unpacking of signals for compatability
+ * across platforms. different Endianness and Native Packing schemes need
+ * to be supported.
+ *
+ ****************************************************************************
+ *
+ * @section REVISION
+ * $Id: //depot/dot11/v6.1/host/lib_sme/common/event_pack_unpack/event_pack_unpack.c#1 $
+ *
+ ****************************************************************************/
+/** @ingroup common
+ * @{
+ */
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* PROJECT INCLUDES *********************************************************/
+#include "abstractions/osa.h"
+#include "event_pack_unpack/event_pack_unpack.h"
+
+/* MACROS *******************************************************************/
+
+/* GLOBAL VARIABLE DEFINITIONS **********************************************/
+
+/* PRIVATE TYPES DEFINITIONS ************************************************/
+
+/* PRIVATE CONSTANT DEFINITIONS *********************************************/
+
+/* PRIVATE VARIABLE DEFINITIONS *********************************************/
+
+/* PRIVATE FUNCTION PROTOTYPES **********************************************/
+
+/* PRIVATE FUNCTION DEFINITIONS *********************************************/
+
+/* PUBLIC FUNCTION DEFINITIONS **********************************************/
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint16 event_pack_uint8 (uint8** resultBuffer, uint8 value)
+{
+ (*resultBuffer)[0] = value;
+ (*resultBuffer)++;
+ return 1;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint16 event_pack_uint16(uint8** resultBuffer, uint16 value)
+{
+ (*resultBuffer)[0] = value & 0xFF;
+ (*resultBuffer)[1] = (value >> 8) & 0xFF;
+ (*resultBuffer) += 2;
+ return 2;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint16 event_pack_uint32(uint8** resultBuffer, uint32 value)
+{
+ (*resultBuffer)[0] = (uint8)value & 0xFF;
+ (*resultBuffer)[1] = (uint8)(value >> 8) & 0xFF;
+ (*resultBuffer)[2] = (uint8)(value >> 16) & 0xFF;
+ (*resultBuffer)[3] = (uint8)(value >> 24) & 0xFF;
+ (*resultBuffer) += 4;
+ return 4;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint16 event_pack_buffer(uint8** resultBuffer, uint8* value, uint16 numberOfBytes)
+{
+ osa_memmove(*resultBuffer, value, numberOfBytes);
+ (*resultBuffer) += numberOfBytes;
+ return numberOfBytes;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint16 event_pack_string(uint8** resultBuffer, unifi_String value)
+{
+ uint16 len = (uint16)osa_strlen(value) + 1;
+ (void)event_pack_int16(resultBuffer, (int16)len);
+ osa_memmove(*resultBuffer, value, len);
+ (*resultBuffer) += len;
+ return len + 2;
+}
+
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint8 event_unpack_uint8 (uint8** signalBuffer)
+{
+ uint8 result = (*signalBuffer)[0];
+ (*signalBuffer)++;
+ return result;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint16 event_unpack_uint16(uint8** signalBuffer)
+{
+ uint16 result = ((*signalBuffer)[1] << 8) |
+ (*signalBuffer)[0];
+ (*signalBuffer)+=2;
+ return result;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+uint32 event_unpack_uint32(uint8** signalBuffer)
+{
+ uint32 result = ((*signalBuffer)[3] << 24) |
+ ((*signalBuffer)[2] << 16) |
+ ((*signalBuffer)[1] << 8) |
+ (*signalBuffer)[0];
+ (*signalBuffer)+=4;
+ return result;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+void event_unpack_buffer(uint8** signalBuffer, uint8* resultBuffer, uint16 numberOfBytes)
+{
+ osa_memmove(resultBuffer, *signalBuffer, numberOfBytes);
+ (*signalBuffer) += numberOfBytes;
+}
+
+/**
+ * See description in event_pack_unpack/event_pack_unpack.h
+ */
+unifi_String event_unpack_string(uint8** signalBuffer)
+{
+ unifi_String result = NULL;
+ uint16 len = (uint16)event_unpack_int16(signalBuffer);
+ if (len > 0)
+ {
+ result = (unifi_String)osa_malloc(len);
+ if (result) {
+ osa_memmove(result, *signalBuffer, len);
+ (*signalBuffer) += len;
+ }
+ }
+
+ return result;
+}
+
+
+uint16 event_pack_hip_header(uint8** signalBuffer, uint16 id, uint16 pid, const DataReference* dataref1, const DataReference* dataref2)
+{
+ (void)event_pack_uint16(signalBuffer, id);
+ (void)event_pack_uint16(signalBuffer, 0);
+ (void)event_pack_uint16(signalBuffer, pid);
+ if (dataref1)
+ {
+ (void)event_pack_uint16(signalBuffer, dataref1->slotNumber);
+ (void)event_pack_uint16(signalBuffer, dataref1->dataLength);
+ }
+ else
+ {
+ (void)event_pack_uint32(signalBuffer, 0);
+ }
+
+ if (dataref2)
+ {
+ (void)event_pack_uint16(signalBuffer, dataref2->slotNumber);
+ (void)event_pack_uint16(signalBuffer, dataref2->dataLength);
+ }
+ else
+ {
+ (void)event_pack_uint32(signalBuffer, 0);
+ }
+ return 14;
+}
+
+
+/** @}
+ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.h
new file mode 100644
index 0000000..edd16a3
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/event_pack_unpack/event_pack_unpack.h
@@ -0,0 +1,91 @@
+/** @file event_pack_unpack.h
+ *
+ * Event Packing and unpacking functions
+ *
+ * @section LEGAL
+ * CONFIDENTIAL
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source for details on the
+ * license terms.
+ *
+ * @section DESCRIPTION
+ * Implements Event Packing and Unpacking of signals for compatability
+ * across platforms. different Endianness and Native Packing schemes need
+ * to be supported.
+ *
+ *
+ ****************************************************************************
+ *
+ * @section REVISION
+ * $Id: //depot/dot11/v6.1/host/lib_sme/common/event_pack_unpack/event_pack_unpack.h#1 $
+ *
+ ****************************************************************************/
+#ifndef EVENT_PACK_UNPACK_H
+#define EVENT_PACK_UNPACK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @ingroup common
+ * @{
+ */
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* PROJECT INCLUDES *********************************************************/
+#include "abstractions/osa.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+
+/* PUBLIC MACROS ************************************************************/
+
+/* PUBLIC TYPES DEFINITIONS *************************************************/
+
+/* PUBLIC CONSTANT DECLARATIONS *********************************************/
+
+/* PUBLIC VARIABLE DECLARATIONS *********************************************/
+
+/* PUBLIC FUNCTION PROTOTYPES ***********************************************/
+
+/**
+ * @brief
+ * Packs data into the result buffer
+ *
+ * @par Description
+ * Packs data into a buffer from Native format into wire format.
+ *
+ * @return
+ * uint16 Number of bytes packed
+ *
+ */
+extern uint16 event_pack_uint8 (uint8** resultBuffer, uint8 value);
+extern uint16 event_pack_uint16(uint8** resultBuffer, uint16 value);
+extern uint16 event_pack_uint32(uint8** resultBuffer, uint32 value);
+#define event_pack_int8(resultBuffer, value) event_pack_uint8(resultBuffer, (uint8)value)
+#define event_pack_int16(resultBuffer, value) event_pack_uint16(resultBuffer, (uint16)value)
+#define event_pack_int32(resultBuffer, value) event_pack_uint32(resultBuffer, (uint32)value)
+extern uint16 event_pack_buffer(uint8** resultBuffer, uint8* value, uint16 numberOfBytes);
+extern uint16 event_pack_string(uint8** resultBuffer, unifi_String value);
+
+extern uint16 event_pack_hip_header(uint8** signalBuffer, uint16 id, uint16 pid, const DataReference* dataref1, const DataReference* dataref2);
+
+
+extern uint8 event_unpack_uint8 (uint8** signalBuffer);
+extern uint16 event_unpack_uint16(uint8** signalBuffer);
+extern uint32 event_unpack_uint32(uint8** signalBuffer);
+#define event_unpack_int8(signalBuffer) (int8)event_unpack_uint8(signalBuffer)
+#define event_unpack_int16(signalBuffer) (int16)event_unpack_uint16(signalBuffer)
+#define event_unpack_int32(signalBuffer) (int32)event_unpack_uint32(signalBuffer)
+extern void event_unpack_buffer(uint8** signalBuffer, uint8* resultBuffer, uint16 numberOfBytes);
+extern unifi_String event_unpack_string(uint8** signalBuffer);
+
+/** @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* EVENT_PACK_UNPACK_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm.h
new file mode 100644
index 0000000..8179782
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm.h
@@ -0,0 +1,242 @@
+/** @file fsm.h
+ *
+ * Public FSM header
+ *
+ * @section LEGAL
+ * CONFIDENTIAL
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source for details on the
+ * license terms.
+ *
+ * @section DESCRIPTION
+ * FSM header for the public FSM api
+ *
+ ****************************************************************************
+ *
+ * @section REVISION
+ * $Id: //depot/dot11/v6.1/host/lib_sme/common/fsm/fsm.h#1 $
+ *
+ ****************************************************************************/
+#ifndef FSM_H
+#define FSM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @{
+ * @ingroup fsm
+ */
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* PROJECT INCLUDES *********************************************************/
+#include "abstractions/osa.h"
+
+/* PUBLIC MACROS ************************************************************/
+
+/* PUBLIC TYPES DEFINITIONS *************************************************/
+
+/**
+ * @brief
+ * Toplevel FSM context data
+ *
+ * @par Description
+ * Holds ALL FSM static and dynamic data for a FSM
+ */
+typedef struct FsmContext FsmContext;
+
+/**
+ * @brief
+ * FSM event header.
+ *
+ * @par Description
+ * All events MUST have this struct as the FIRST member.
+ * The next member is used internally for linked lists
+ */
+typedef struct FsmEvent
+{
+ struct FsmEvent *next;
+ uint16 id;
+ uint16 destination;
+ uint16 sender_; /* trailing underscore to avoid clash with #define */
+} FsmEvent;
+
+/**
+ * @brief
+ * FSM timer Info
+ *
+ * @par Description
+ * Min timeout time and allowable extra time before timeout
+ */
+typedef struct FsmTimerData
+{
+ uint32 timeoutTimeMs;
+ uint16 timeoutTimeExtraMs;
+} FsmTimerData;
+
+/**
+ * @brief
+ * FSM External Wakeup CallbackFunction Pointer
+ *
+ * @par Description
+ * Defines the external wakeup function for the FSM
+ * to call when an external event is injected into the systen
+ *
+ * @param[in] context : External context
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmExternalWakupCallbackPtr) (void* context);
+
+/* PUBLIC CONSTANT DECLARATIONS *********************************************/
+
+/* PUBLIC VARIABLE DECLARATIONS *********************************************/
+
+/* PUBLIC FUNCTION PROTOTYPES ***********************************************/
+
+/**
+ * @brief
+ * Initialises a top level FSM context
+ *
+ * @par Description
+ * Initialises the FSM Context to an initial state and allocates
+ * space for "maxProcesses" number of instances
+ *
+ * @param[in] osaContext : OSA context
+ * @param[in] applicationContext : Internal fsm application context
+ * @param[in] externalContext : External context
+ * @param[in] maxProcesses : Max processes to allocate room for
+ *
+ * @return
+ * FsmContext* fsm context
+ */
+extern FsmContext* fsm_init_context(void* applicationContext, void* externalContext, uint16 maxProcesses);
+
+/**
+ * @brief
+ * Resets the FSM's back to first conditions
+ *
+ * @par Description
+ * This function is used to free any dynamic resources allocated for the
+ * given context by fsm_init_context().
+ * The FSM's reset function is called to cleanup any fsm specific memory
+ * The reset funtion does NOT need to free the fsm data pointer as
+ * fsm_shutdown() will do it.
+ * the FSM's init function is call again to reinitialise the FSM context.
+ * fsm_reset() should NEVER be called when fsm_execute() is running.
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * void
+ */
+extern void fsm_reset(FsmContext* context);
+
+/**
+ * @brief
+ * Frees resources allocated by fsm_init_context
+ *
+ * @par Description
+ * This function is used to free any dynamic resources allocated for the
+ * given context by fsm_init_context(), prior to complete termination of
+ * the program.
+ * The FSM's reset function is called to cleanup any fsm specific memory.
+ * The reset funtion does NOT need to free the fsm data pointer as
+ * fsm_shutdown() will do it.
+ * fsm_shutdown() should NEVER be called when fsm_execute() is running.
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * void
+ */
+extern void fsm_shutdown(FsmContext* context);
+
+/**
+ * @brief
+ * Executes the fsm context
+ *
+ * @par Description
+ * Executes the FSM context and runs until ALL events in the context are processed.
+ * When no more events are left to process then fsm_execute() returns to a time
+ * specifying when to next call the fsm_execute()
+ * Scheduling, threading, blocking and external event notification are outside
+ * the scope of the FSM and fsm_execute().
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * FsmTimerData absolute time + allowed variation for next timeout OR 0xFFFFFFFF if no timers are set
+ */
+extern FsmTimerData fsm_execute(FsmContext* context);
+
+/**
+ * @brief
+ * Adds an event to the FSM context's external event queue for processing
+ *
+ * @par Description
+ * Adds an event to the contexts external queue
+ * This is thread safe and adds an event to the fsm's external event queue.
+ *
+ * @param[in] context : FSM context
+ * @param[in] event : event to add to the event queue
+ * @param[in] destination : destination of the event
+ * @param[in] id : event id
+ *
+ * @return
+ * void
+ */
+extern void fsm_send_event_external(FsmContext *context, FsmEvent* event, uint16 destination, uint16 id);
+
+/**
+ * @brief
+ * Gets the time until the next FSM timer expiry
+ *
+ * @par Description
+ * Returns the next timeout time or 0 if no timers are set.
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * FsmTimerData The absolute time and allowed extra for the next timer expiry or 0xFFFFFFFF if no timers are set
+ */
+extern FsmTimerData fsm_get_next_timeout(FsmContext *context);
+
+
+/**
+ * @brief
+ * Check if the fsm has events to process
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * Boolean returns TRUE if there are events for the FSM to process
+ */
+extern Boolean fsm_has_events(FsmContext* context);
+
+/**
+ * @brief
+ * function that installs the contexts wakeup function
+ *
+ * @param[in] context : FSM context
+ * @param[in] callback : Callback function pointer
+ *
+ * @return
+ * void
+ */
+extern void fsm_install_wakeup_callback(FsmContext* context, FsmExternalWakupCallbackPtr callback);
+
+
+/** @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FSM_H */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm_types.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm_types.h
new file mode 100644
index 0000000..9875f81
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/fsm/fsm_types.h
@@ -0,0 +1,412 @@
+/** @file fsm_types.h
+ *
+ * FSM Types definitions
+ *
+ * @section LEGAL
+ * CONFIDENTIAL
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source for details on the
+ * license terms.
+ *
+ * @section DESCRIPTION
+ * FSM Types
+ *
+ ****************************************************************************
+ *
+ * @section REVISION
+ * $Id: //depot/dot11/v6.1/host/lib_sme/common/fsm/fsm_types.h#1 $
+ *
+ ****************************************************************************/
+#ifndef FSM_TYPES_H
+#define FSM_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @{
+ * @ingroup fsm
+ */
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* PROJECT INCLUDES *********************************************************/
+#include "abstractions/osa.h"
+#include "fsm/fsm.h"
+
+/* MACROS *******************************************************************/
+#define FSM_MAX_TRANSITION_HISTORY 10
+
+/* GLOBAL VARIABLE DEFINITIONS **********************************************/
+
+/* PUBLIC TYPES DEFINITIONS *************************************************/
+
+/**
+ * @brief
+ * FSM event list header.
+ *
+ * @par Description
+ * Singly linked list of events.
+ */
+typedef struct FsmEventList
+{
+ FsmEvent *first;
+ FsmEvent *last;
+} FsmEventList;
+
+
+/**
+ * @brief
+ * FSM timer id.
+ *
+ * @par Description
+ * Composite Id made up of the id, dest and a unique id so
+ * fsm_remove_timer knows where to look when removing the timer
+ */
+typedef struct FsmTimerId
+{
+ uint16 id;
+ uint16 destination;
+ uint16 uniqueid;
+} FsmTimerId;
+
+/**
+ * @brief
+ * FSM timer header.
+ *
+ * @par Description
+ * All timer MUST have this struct as the FIRST member.
+ * The first members of the structure MUST remain compatable
+ * with the FsmEvent so that timers are just specialised events
+ */
+typedef struct FsmTimer
+{
+ struct FsmTimer *next;
+ uint16 id;
+ uint16 destination;
+ uint16 sender_; /* trailing underscore to avoid clash with #define */
+
+ FsmTimerId timerid;
+ FsmTimerData timeoutData;
+} FsmTimer;
+
+/**
+ * @brief
+ * FSM timer list header.
+ *
+ * @par Description
+ * Singly linked list of timers.
+ */
+typedef struct FsmTimerList
+{
+ FsmTimer *first;
+ FsmTimer *last;
+ uint16 nexttimerid;
+} FsmTimerList;
+
+/**
+ * @brief
+ * Process Entry Function Pointer
+ *
+ * @par Description
+ * Defines the entry function for a processes.
+ * Called at process initialisation.
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmProcEntryFnPtr) (FsmContext* context);
+
+/**
+ * @brief
+ * Process Transition Function Pointer
+ *
+ * @par Description
+ * Defines a transition function for a processes.
+ * Called when an event causes a transition on a process
+ *
+ * @param[in] context : FSM context
+ * @param[in] event : event to process
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmTransitionFnPtr)(FsmContext* context, const FsmEvent* event);
+
+/**
+ * @brief
+ * Process reset/shutdown Function Pointer
+ *
+ * @par Description
+ * Defines the reset/shutdown function for a processes.
+ * Called to reset or shutdown an fsm.
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmProcResetFnPtr) (FsmContext* context);
+
+#ifdef FSM_DEBUG_DUMP
+/**
+ * @brief
+ * Trace Dump Function Pointer
+ *
+ * @par Description
+ * Called when we want to trace the FSM
+ *
+ * @param[in] context : FSM context
+ * @param[in] id : fsm id
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmDumpFnPtr)(FsmContext* context, const uint16 id);
+#endif
+
+/**
+ * @brief
+ * Event ID to transition function entry
+ *
+ * @par Description
+ * Event ID to Transition Entry in a state table.
+ */
+typedef struct
+{
+ uint16 eventid;
+ FsmTransitionFnPtr transition;
+#ifdef FSM_DEBUG
+ const char* transitionName;
+#endif
+} FsmEventEntry;
+
+/**
+ * @brief
+ * Single State's Transition Table
+ *
+ * @par Description
+ * Stores Data for a single State's event to
+ * transition functions mapping
+ */
+typedef struct
+{
+ const uint8 numEntries;
+ const Boolean saveAll;
+ const FsmEventEntry* eventEntryArray; /* array of transition function pointers for state */
+#ifdef FSM_DEBUG
+ uint16 stateNumber;
+ const char* stateName;
+#endif
+} FsmTableEntry;
+
+/**
+ * @brief
+ * Process State Transtion table
+ *
+ * @par Description
+ * Stores Data for a processes State to transition table
+ */
+typedef struct
+{
+ uint16 numStates; /* number of states */
+ const FsmTableEntry* aStateEventMatrix; /* state event matrix */
+} FsmTransitionFunctionTable;
+
+/**
+ * @brief
+ * Const Process definition
+ *
+ * @par Description
+ * Constant process specification.
+ * This is ALL the non dynamic data that defines
+ * a process.
+ */
+typedef struct
+{
+#ifdef FSM_DEBUG
+ const char* processName;
+#endif
+ const uint32 processId;
+ const FsmTransitionFunctionTable transitionTable;
+ const FsmTableEntry unhandledTransitions;
+ const FsmTableEntry ignoreFunctions;
+ const FsmProcEntryFnPtr entryFn;
+ const FsmProcResetFnPtr resetFn;
+#ifdef FSM_DEBUG_DUMP
+ const FsmDumpFnPtr dumpFn; /* Called to dump fsm specific trace if not NULL */
+#endif
+} FsmProcessStateMachine;
+
+#ifdef FSM_DEBUG_DUMP
+/**
+ * @brief
+ * Storage for state transition info
+ */
+typedef struct
+{
+ uint16 transitionNumber;
+ FsmEvent event;
+ uint16 fromState;
+ uint16 toState;
+ FsmTransitionFnPtr transitionFn;
+ uint16 transitionCount; /* number consecutive of times this transition was seen */
+#ifdef FSM_DEBUG
+ const char* transitionName;
+#endif
+} FsmTransitionRecord;
+
+/**
+ * @brief
+ * Storage for the last state X transitions
+ */
+typedef struct
+{
+ uint16 numTransitions;
+ FsmTransitionRecord records[FSM_MAX_TRANSITION_HISTORY];
+} FsmTransitionRecords;
+#endif
+
+/**
+ * @brief
+ * Dynamic Process data
+ *
+ * @par Description
+ * Dynamic process data that is used to keep track of the
+ * state and data for a process instance
+ */
+typedef struct
+{
+ const FsmProcessStateMachine* fsmInfo; /* state machine info that is constant regardless of context */
+ uint16 instanceId; /* Runtime process id */
+ uint16 state; /* Current state */
+ void* params; /* Instance user data */
+ FsmEventList savedEventQueue; /* The saved event queue */
+#ifdef FSM_DEBUG_DUMP
+ FsmTransitionRecords transitionRecords; /* Last X transitions in the FSM */
+#endif
+} FsmInstanceEntry;
+
+/**
+ * @brief
+ * OnCreate Callback Function Pointer
+ *
+ * @par Description
+ * Called when an fsm is created.
+ *
+ * @param[in] extContext : External context
+ * @param[in] instance : FSM instance
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmOnCreateFnPtr) (void* extContext, const FsmInstanceEntry* instance);
+
+/**
+ * @brief
+ * OnTransition Callback Function Pointer
+ *
+ * @par Description
+ * Called when an event is processed by a fsm
+ *
+ * @param[in] extContext : External context
+ * @param[in] eventEntryArray : Entry data
+ * @param[in] event : Event
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmOnTransitionFnPtr) (void* extContext, const FsmEventEntry* eventEntryArray, const FsmEvent* event);
+
+/**
+ * @brief
+ * OnStateChange Callback Function Pointer
+ *
+ * @par Description
+ * Called when fsm_next_state is called
+ *
+ * @param[in] extContext : External context
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmOnStateChangeFnPtr) (void* extContext, uint16 nextstate);
+
+/**
+ * @brief
+ * OnIgnore,OnError or OnInvalid Callback Function Pointer
+ *
+ * @par Description
+ * Called when an event is processed by a fsm
+ *
+ * @param[in] extContext : External context
+ * @param[in] event : Event
+ *
+ * @return
+ * void
+ */
+typedef void (*FsmOnEventFnPtr) (void* extContext, const FsmEvent* event);
+
+/**
+ * @brief
+ * Toplevel FSM context data
+ *
+ * @par Description
+ * Holds ALL FSM static and dynamic data for a FSM
+ */
+struct FsmContext
+{
+ FsmEventList eventQueue; /* The internal event queue */
+ FsmEventList externalEventQueue; /* The external event queue */
+ OsaMutex* externalEventQueueLock; /* The external event queue mutex */
+ FsmTimerList timerQueue; /* The internal timer queue */
+ Boolean useTempSaveList; /* Should the temp save list be used */
+ FsmEventList tempSaveList; /* The temp save event queue */
+ FsmEvent* eventForwardedOrSaved; /* The event that was forwarded or Saved */
+ uint16 maxProcesses; /* Size of instanceArray */
+ uint16 numProcesses; /* Current number allocated in instanceArray */
+ FsmInstanceEntry* instanceArray; /* Array of processes for this component */
+ FsmInstanceEntry* currentInstance; /* Current Process that is executing */
+ FsmExternalWakupCallbackPtr externalEventFn; /* External event Callback */
+ FsmOnEventFnPtr appIgnoreCallback; /* Application Ignore event Callback */
+
+ void* applicationContext; /* Internal fsm application context */
+ void* externalContext; /* External context (set by the userof the fsm) */
+
+#ifdef FSM_TRANSITION_LOCK
+ OsaMutex* transitionLock; /* Lock when calling transition functions */
+#endif
+
+#ifdef FSM_DEBUG
+ FsmOnCreateFnPtr onCreate; /* Debug Transition Callback */
+ FsmOnTransitionFnPtr onTransition; /* Debug Transition Callback */
+ FsmOnTransitionFnPtr onUnhandedCallback; /* Unhanded event Callback */
+ FsmOnStateChangeFnPtr onStateChange; /* Debug State Change Callback */
+ FsmOnEventFnPtr onIgnoreCallback; /* Ignore event Callback */
+ FsmOnEventFnPtr onSaveCallback; /* Save event Callback */
+ FsmOnEventFnPtr onErrorCallback; /* Error event Callback */
+ FsmOnEventFnPtr onInvalidCallback; /* Invalid event Callback */
+#endif
+#ifdef FSM_DEBUG_DUMP
+ uint16 masterTransitionNumber; /* Increments on every transition */
+#endif
+};
+
+/* PUBLIC CONSTANT DECLARATIONS *********************************************/
+
+/* PUBLIC VARIABLE DECLARATIONS *********************************************/
+
+/* PUBLIC FUNCTION PROTOTYPES ***********************************************/
+
+/** @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FSM_TYPES_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/hostio/hip_fsm_types.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/hostio/hip_fsm_types.h
new file mode 100644
index 0000000..e1e3bfa
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/hostio/hip_fsm_types.h
@@ -0,0 +1,517 @@
+/* This is an autogenerated file from sme___fsm_type_gen */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+/* This is an autogenerated file from sme___fsm_type_gen.pl */
+
+
+#ifndef HIP_SIGNALS_XML_TYPES_H
+#define HIP_SIGNALS_XML_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* ENUM DEFINITIONS ********************************************************/
+typedef enum AntennaId
+{
+ AntennaId_AntennaUnknown = 0x0000,
+ AntennaId_Antenna1 = 0x0001,
+ AntennaId_Antenna2 = 0x0002,
+ AntennaId_AntennaMultiple = 0x00ff
+} AntennaId;
+
+typedef enum AuthenticationType
+{
+ AuthenticationType_OpenSystem = 0x0000,
+ AuthenticationType_SharedKey = 0x0001,
+ AuthenticationType_FastBssTransition = 0x0002
+} AuthenticationType;
+
+typedef enum BssType
+{
+ BssType_Infrastructure = 0x0000,
+ BssType_Independent = 0x0001,
+ BssType_AnyBss = 0x0002
+} BssType;
+
+typedef enum BlockAckPolicy
+{
+ BlockAckPolicy_Delayed = 0x0000,
+ BlockAckPolicy_Immediate = 0x0001
+} BlockAckPolicy;
+
+typedef enum BootLoaderOperation
+{
+ BootLoaderOperation_BootLoaderIdle = 0x00,
+ BootLoaderOperation_BootLoaderRestart = 0x01,
+ BootLoaderOperation_BootLoaderPatch = 0x02,
+ BootLoaderOperation_BootLoaderImage0 = 0x10,
+ BootLoaderOperation_BootLoaderImage1 = 0x11,
+ BootLoaderOperation_BootLoaderImage2 = 0x12,
+ BootLoaderOperation_BootLoaderImage3 = 0x13
+} BootLoaderOperation;
+
+typedef enum ChannelOffset
+{
+ ChannelOffset_Scn = 0x0000,
+ ChannelOffset_Sca = 0x0001,
+ ChannelOffset_Scb = 0x0003
+} ChannelOffset;
+
+typedef enum ChannelSwitchMode
+{
+ ChannelSwitchMode_Continue = 0x0000,
+ ChannelSwitchMode_PauseUntilSwitch = 0x0001
+} ChannelSwitchMode;
+
+typedef enum CoexistenceDirection
+{
+ CoexistenceDirection_CoexistenceNone = 0x0000,
+ CoexistenceDirection_CoexistenceDot11Input = 0x0001,
+ CoexistenceDirection_CoexistenceDot11Output = 0x0002
+} CoexistenceDirection;
+
+typedef enum ConnectionStatus
+{
+ ConnectionStatus_Disconnected = 0x0000,
+ ConnectionStatus_Connected = 0x0001
+} ConnectionStatus;
+
+typedef enum Initiator
+{
+ Initiator_Recipient = 0x0000,
+ Initiator_Originator = 0x0001
+} Initiator;
+
+typedef enum Interface
+{
+ Interface_Index2g4 = 0x0001,
+ Interface_Index5g = 0x0002
+} Interface;
+
+typedef enum KeyType
+{
+ KeyType_Group = 0x0000,
+ KeyType_Pairwise = 0x0001,
+ KeyType_Stakey = 0x0002,
+ KeyType_Igtk = 0x0003
+} KeyType;
+
+typedef enum LinkMarginCategory
+{
+ LinkMarginCategory_Ulm = 0x0001,
+ LinkMarginCategory_Dlm = 0x0002,
+ LinkMarginCategory_All = 0xffff
+} LinkMarginCategory;
+
+typedef enum LoaderOperation
+{
+ LoaderOperation_LoaderIdle = 0x0000,
+ LoaderOperation_LoaderCopy = 0x0001
+} LoaderOperation;
+
+typedef enum MibStatus
+{
+ MibStatus_Successful = 0x0000,
+ MibStatus_InvalidParameters = 0x0001,
+ MibStatus_WriteOnly = 0x0002,
+ MibStatus_ReadOnly = 0x0003
+} MibStatus;
+
+typedef enum MeasurementCategory
+{
+ MeasurementCategory_SpectrumManagement = 0x0000,
+ MeasurementCategory_RadioMeasurement = 0x0005,
+ MeasurementCategory_CcxMeasurement = 0x0006
+} MeasurementCategory;
+
+typedef enum MemorySpace
+{
+ MemorySpace_None = 0x00,
+ MemorySpace_SharedDataMemory = 0x01,
+ MemorySpace_ExternalFlashMemory = 0x02,
+ MemorySpace_ExternalSram = 0x03,
+ MemorySpace_Registers = 0x04,
+ MemorySpace_PhyProcessorDataMemory = 0x10,
+ MemorySpace_PhyProcessorProgramMemory = 0x11,
+ MemorySpace_PhyProcessorRom = 0x12,
+ MemorySpace_MacProcessorDataMemory = 0x20,
+ MemorySpace_MacProcessorProgramMemory = 0x21,
+ MemorySpace_MacProcessorRom = 0x22,
+ MemorySpace_BtProcessorDataMemory = 0x30,
+ MemorySpace_BtProcessorProgramMemory = 0x31,
+ MemorySpace_BtProcessorRom = 0x32
+} MemorySpace;
+
+typedef enum NeighborReportRequestType
+{
+ NeighborReportRequestType_Basic = 0x0000,
+ NeighborReportRequestType_TbttOffset = 0x0001
+} NeighborReportRequestType;
+
+typedef enum PeriodicSchedulingMode
+{
+ PeriodicSchedulingMode_PeriodicScheduleNone = 0x0000,
+ PeriodicSchedulingMode_PeriodicSchedulePsPoll = 0x0001,
+ PeriodicSchedulingMode_PeriodicSchedulePmBit = 0x0002,
+ PeriodicSchedulingMode_PeriodicScheduleUapsd = 0x0004,
+ PeriodicSchedulingMode_PeriodicScheduleSapsd = 0x0008,
+ PeriodicSchedulingMode_PeriodicScheduleCts = 0x0010
+} PeriodicSchedulingMode;
+
+typedef enum PowerManagementMode
+{
+ PowerManagementMode_ActiveMode = 0x0000,
+ PowerManagementMode_PowerSave = 0x0001,
+ PowerManagementMode_FastPowerSave = 0x0002
+} PowerManagementMode;
+
+typedef enum Priority
+{
+ Priority_QosUp0 = 0x0000,
+ Priority_QosUp1 = 0x0001,
+ Priority_QosUp2 = 0x0002,
+ Priority_QosUp3 = 0x0003,
+ Priority_QosUp4 = 0x0004,
+ Priority_QosUp5 = 0x0005,
+ Priority_QosUp6 = 0x0006,
+ Priority_QosUp7 = 0x0007,
+ Priority_QosTsid0 = 0x0008,
+ Priority_QosTsid1 = 0x0009,
+ Priority_QosTsid2 = 0x000a,
+ Priority_QosTsid3 = 0x000b,
+ Priority_QosTsid4 = 0x000c,
+ Priority_QosTsid5 = 0x000d,
+ Priority_QosTsid6 = 0x000e,
+ Priority_QosTsid7 = 0x000f,
+ Priority_Contention = 0x8000,
+ Priority_ContentionFree = 0x8001
+} Priority;
+
+typedef enum ProtectType
+{
+ ProtectType_None = 0x0000,
+ ProtectType_Rx = 0x0001,
+ ProtectType_Tx = 0x0002,
+ ProtectType_RxTx = 0x0003,
+ ProtectType_RxMmpdu = 0x0004,
+ ProtectType_TxMmpdu = 0x0005,
+ ProtectType_RxTxMmpdu = 0x0006
+} ProtectType;
+
+typedef enum ReasonCode
+{
+ ReasonCode_UnspecifiedReason = 0x0001,
+ ReasonCode_AuthenticationNotValid = 0x0002,
+ ReasonCode_DeauthenticatedLeaveBss = 0x0003,
+ ReasonCode_DisassociatedInactivity = 0x0004,
+ ReasonCode_ApOverload = 0x0005,
+ ReasonCode_Class2FrameError = 0x0006,
+ ReasonCode_Class3FrameError = 0x0007,
+ ReasonCode_DisassociatedLeaveBss = 0x0008,
+ ReasonCode_AssociationNotAuthenticated = 0x0009,
+ ReasonCode_DisassociatedPowerCapability = 0x000a,
+ ReasonCode_DisassociatedSupportedChannels = 0x000b,
+ ReasonCode_InvalidInformationElement = 0x000d,
+ ReasonCode_MichaelMicFailure = 0x000e,
+ ReasonCode_FourwayHandshakeTimeout = 0x000f,
+ ReasonCode_GroupKeyUpdateTimeout = 0x0010,
+ ReasonCode_HandshakeElementDifferent = 0x0011,
+ ReasonCode_InvalidGroupCipher = 0x0012,
+ ReasonCode_InvalidPairwiseCipher = 0x0013,
+ ReasonCode_InvalidAkmp = 0x0014,
+ ReasonCode_UnsupportedRsnIeVersion = 0x0015,
+ ReasonCode_InvalidRsnIeCapabilities = 0x0016,
+ ReasonCode_Dot1xAuthFailed = 0x0017,
+ ReasonCode_CipherRejectedByPolicy = 0x0018,
+ ReasonCode_ServiceChangePrecludesTs = 0x001F,
+ ReasonCode_QosUnspecifiedReason = 0x0020,
+ ReasonCode_QosInsufficientBandwidth = 0x0021,
+ ReasonCode_QosExcessiveNotAck = 0x0022,
+ ReasonCode_QosTxopLimitExceeded = 0x0023,
+ ReasonCode_QstaLeaving = 0x0024,
+ ReasonCode_EndBa = 0x0025,
+ ReasonCode_EndDls = 0x0025,
+ ReasonCode_EndTs = 0x0025,
+ ReasonCode_UnknownDls = 0x0026,
+ ReasonCode_UnknownBa = 0x0026,
+ ReasonCode_UnknownTs = 0x0026,
+ ReasonCode_Timeout = 0x0027,
+ ReasonCode_StakeyMismatch = 0x002d
+} ReasonCode;
+
+typedef enum ReceptionStatus
+{
+ ReceptionStatus_RxSuccess = 0x0000,
+ ReceptionStatus_RxFailure = 0x0001
+} ReceptionStatus;
+
+typedef enum ResultCode
+{
+ ResultCode_Success = 0x0000,
+ ResultCode_UnspecifiedFailure = 0x0001,
+ ResultCode_RefusedCapabilitiesMismatch = 0x000a,
+ ResultCode_ReassociationDeniedNoAssociation = 0x000b,
+ ResultCode_RefusedExternalReason = 0x000c,
+ ResultCode_RefusedAuthenticationMismatch = 0x000d,
+ ResultCode_RefusedInvalidAuthenticationSequenceNumber = 0x000e,
+ ResultCode_RefusedChallengeFailure = 0x000f,
+ ResultCode_RefusedAuthenticationTimeout = 0x0010,
+ ResultCode_RefusedApOutOfMemory = 0x0011,
+ ResultCode_RefusedBasicRatesMismatch = 0x0012,
+ ResultCode_RefusedShortPreambleRequired = 0x0013,
+ ResultCode_RefusedPbccModulationRequired = 0x0014,
+ ResultCode_RefusedChannelAgilityRequired = 0x0015,
+ ResultCode_RefusedSpectrumManagementRequired = 0x0016,
+ ResultCode_RefusedPowerCapabilityUnacceptable = 0x0017,
+ ResultCode_RefusedSupportedChannelsUnacceptable = 0x0018,
+ ResultCode_RefusedShortSlotRequired = 0x0019,
+ ResultCode_RefusedDsssOfdmRequired = 0x001a,
+ ResultCode_RefusedNoHtSupport = 0x001b,
+ ResultCode_R0khUnreachable = 0x001c,
+ ResultCode_RefusedPcoTransitionSupport = 0x001d,
+ ResultCode_Failure = 0x0020,
+ ResultCode_RefusedApBandwidthInsufficient = 0x0021,
+ ResultCode_RefusedPoorOperatingChannel = 0x0022,
+ ResultCode_RefusedQosRequired = 0x0023,
+ ResultCode_Refused = 0x0025,
+ ResultCode_RefusedReasonUnspecified = 0x0025,
+ ResultCode_InvalidParameters = 0x0026,
+ ResultCode_RejectedWithSuggestedTspecChanges = 0x0027,
+ ResultCode_RejectedInvalidIe = 0x0028,
+ ResultCode_RejectedInvalidGroupCipher = 0x0029,
+ ResultCode_RejectedInvalidPairwiseCipher = 0x002a,
+ ResultCode_RejectedInvalidAkmp = 0x002b,
+ ResultCode_RejectedUnsupportedRsnVersion = 0x002c,
+ ResultCode_RejectedInvalidRsnCapability = 0x002d,
+ ResultCode_RejectedSecurityPolicy = 0x002e,
+ ResultCode_RejectedForDelayPeriod = 0x002f,
+ ResultCode_NotAllowed = 0x0030,
+ ResultCode_NotPresent = 0x0031,
+ ResultCode_NotQsta = 0x0032,
+ ResultCode_RejectedListenintervalTooLarge = 0x0033,
+ ResultCode_InvalidFtActionFrameCount = 0x0034,
+ ResultCode_InvalidPmkid = 0x0035,
+ ResultCode_InvalidMdie = 0x0036,
+ ResultCode_InvalidFtie = 0x0037,
+ ResultCode_UnspecifiedQosFailure = 0x00c8,
+ ResultCode_WrongPolicy = 0x00c9,
+ ResultCode_InsufficientBandwidth = 0x00ca,
+ ResultCode_InvalidTspecParameters = 0x00cb,
+ ResultCode_Timeout = 0x8000,
+ ResultCode_TooManySimultaneousRequests = 0x8001,
+ ResultCode_BssAlreadyStartedOrJoined = 0x8002,
+ ResultCode_NotSupported = 0x8003,
+ ResultCode_TransmissionFailure = 0x8004,
+ ResultCode_RefusedNotAuthenticated = 0x8005,
+ ResultCode_ResetRequiredBeforeStart = 0x8006,
+ ResultCode_LmInfoUnavailable = 0x8007
+} ResultCode;
+
+typedef enum RoutingInformation
+{
+ RoutingInformation_NullRt = 0x0000
+} RoutingInformation;
+
+typedef enum ScanType
+{
+ ScanType_ActiveScan = 0x0000,
+ ScanType_PassiveScan = 0x0001
+} ScanType;
+
+typedef enum ServiceClass
+{
+ ServiceClass_ReorderableMulticast = 0x0000,
+ ServiceClass_StrictlyOrdered = 0x0001,
+ ServiceClass_QosAck = 0x0002,
+ ServiceClass_QosNoAck = 0x0003,
+ ServiceClass_QosLocalMulticast = 0x0004
+} ServiceClass;
+
+typedef enum SnifferReceptionStatus
+{
+ SnifferReceptionStatus_Success = 0x0000,
+ SnifferReceptionStatus_UnsupportedModulation = 0x0001,
+ SnifferReceptionStatus_BadFcs = 0x0002,
+ SnifferReceptionStatus_BadSignal = 0x0003
+} SnifferReceptionStatus;
+
+typedef enum SourceType
+{
+ SourceType_ScrAp = 0x0000,
+ SourceType_ScrPortal = 0x0001
+} SourceType;
+
+typedef enum SymbolId
+{
+ SymbolId_SltEnd = 0x0000,
+ SymbolId_SltPciSlotConfig = 0x0001,
+ SymbolId_SltSdioSlotConfig = 0x0002,
+ SymbolId_SltBuildIdNumber = 0x0003,
+ SymbolId_SltBuildIdString = 0x0004,
+ SymbolId_SltPersistentStoreDb = 0x0005,
+ SymbolId_SltResetVectorPhy = 0x0006,
+ SymbolId_SltResetVectorMac = 0x0007,
+ SymbolId_SltSdioLoaderControl = 0x0008,
+ SymbolId_SltTestCmd = 0x0009,
+ SymbolId_SltTestAliveCounter = 0x000a,
+ SymbolId_SltTestParameters = 0x000b,
+ SymbolId_SltTestResults = 0x000c,
+ SymbolId_SltTestVersion = 0x000d,
+ SymbolId_SltMibPsidRanges = 0x000e,
+ SymbolId_SltKipTable = 0x000f,
+ SymbolId_SltPanicDataPhy = 0x0010,
+ SymbolId_SltPanicDataMac = 0x0011,
+ SymbolId_SltBootLoaderControl = 0x0012
+} SymbolId;
+
+typedef enum TransmissionStatus
+{
+ TransmissionStatus_Successful = 0x0000,
+ TransmissionStatus_RetryLimit = 0x0001,
+ TransmissionStatus_TxLifetime = 0x0002,
+ TransmissionStatus_NoBss = 0x0003,
+ TransmissionStatus_ExcessiveDataLength = 0x0004,
+ TransmissionStatus_NonNullSourceRouting = 0x0005,
+ TransmissionStatus_UnsupportedPriority = 0x0006,
+ TransmissionStatus_UnavailablePriority = 0x0007,
+ TransmissionStatus_UnsupportedServiceClass = 0x0008,
+ TransmissionStatus_UnavailableServiceClass = 0x0009,
+ TransmissionStatus_UnavailableKeyMapping = 0x000a,
+ TransmissionStatus_TxEdcaTimeout = 0x000b,
+ TransmissionStatus_BlockAckTimeout = 0x000c
+} TransmissionStatus;
+
+typedef enum UnitDataFilterMode
+{
+ UnitDataFilterMode_OptOut = 0x0000,
+ UnitDataFilterMode_OptIn = 0x0003
+} UnitDataFilterMode;
+
+typedef enum UpdateType
+{
+ UpdateType_Add = 0x0000,
+ UpdateType_Move = 0x0001,
+ UpdateType_Delete = 0x0002
+} UpdateType;
+
+
+/* CONST TYPES DEFINITIONS ********************************************************/
+
+
+/* POINTER TYPES DEFINITIONS ********************************************************/
+
+/* SIMPLE TYPES DEFINITIONS ********************************************************/
+typedef uint16 AssociationId;
+
+typedef uint16 AutonomousScanId;
+
+typedef uint16 BeaconPeriods;
+
+typedef uint8 BufferHandleValue;
+
+typedef uint16 CapabilityInformation;
+
+typedef uint8 ChannelNumberValue;
+
+typedef uint16 ChannelStartingFactor;
+
+typedef uint32 CipherSuiteSelector;
+
+typedef uint32 ClientTag;
+
+typedef uint16 DataLength;
+
+typedef int16 Decibels;
+
+typedef uint8 DialogTokenValue;
+
+typedef int32 HertzDelta;
+
+typedef uint32 Ipv4Address;
+
+typedef struct unifi_MACAddress
+{
+ uint8 data[6];
+} unifi_MACAddress;
+
+typedef uint16 Megahertz;
+
+typedef struct MemoryOffset
+{
+ uint8 data[3];
+} MemoryOffset;
+
+typedef uint16 Microseconds16;
+
+typedef uint32 Microseconds32;
+
+typedef uint32 PciPointer;
+
+typedef uint8 PhyType;
+
+typedef uint16 PeriodicId;
+
+typedef uint8 RcpiValue;
+
+typedef uint8 RsniValue;
+
+typedef struct ReceiveSequenceCount
+{
+ uint8 data[8];
+} ReceiveSequenceCount;
+typedef uint16 Seconds;
+
+typedef uint16 SimplePointer;
+
+typedef uint16 SlotNumber;
+
+typedef struct TsfTime
+{
+ uint8 data[8];
+} TsfTime;
+typedef struct TsInfoValue
+{
+ uint8 data[3];
+} TsInfoValue;
+
+typedef uint16 TimeUnits;
+
+typedef uint16 TriggeredId;
+
+typedef uint16 BufferHandle;
+
+typedef uint16 ChannelNumber;
+
+typedef uint16 DialogToken;
+
+typedef uint16 Rcpi;
+
+typedef uint16 Rsni;
+
+typedef uint16 Rate;
+
+typedef uint16 ReportedFrame;
+
+typedef uint16 SequenceNumber;
+
+typedef uint32 TsInfo;
+
+
+/* COMPLEX TYPES DEFINITIONS ********************************************************/
+typedef struct DataReference
+{
+ SlotNumber slotNumber;
+ DataLength dataLength;
+}DataReference;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*HIP_SIGNALS_XML_TYPES_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/sme_trace/sme_trace.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/sme_trace/sme_trace.h
new file mode 100644
index 0000000..ce46884
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/sme_trace/sme_trace.h
@@ -0,0 +1,242 @@
+/** @file sme_trace.h
+ *
+ * Trace facilities for the SME
+ *
+ * @section LEGAL
+ * CONFIDENTIAL
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source for details on the
+ * license terms.
+ *
+ * @section DESCRIPTION
+ * Provides prototypes for the SME trace facilities
+ *
+ ****************************************************************************
+ *
+ * @section REVISION
+ * $Id: //depot/dot11/v6.1/host/lib_sme/common/sme_trace/sme_trace.h#1 $
+ *
+ ****************************************************************************/
+
+#ifndef SME_TRACE_H
+#define SME_TRACE_H
+
+#include "abstractions/osa.h"
+
+typedef enum sme_trace_level
+{
+ TR_LVL_ENTRY,
+ TR_LVL_DEBUG,
+ TR_LVL_INFO,
+ TR_LVL_WARN,
+ TR_LVL_ERROR,
+ TR_LVL_CRIT,
+ TR_LVL_OFF
+} sme_trace_level;
+
+/*
+ * Add New Trace ID's here...
+ * Only add to the end before LAST_MODULE_ID
+ */
+typedef enum sme_trace_module_id
+{
+ /* ----------------------------------------- */
+ /* SME TRACE CODE */
+ /* ----------------------------------------- */
+ TR_SME_TRACE,
+ /* ----------------------------------------- */
+
+ /* ----------------------------------------- */
+ /* SME LIBS */
+ /* ----------------------------------------- */
+ TR_CSR_LIST,
+ TR_IE_ACCESS,
+ TR_IE_PRINT,
+ TR_PAYLOAD_MGR,
+ TR_OSA,
+ TR_IPC,
+ /* ----------------------------------------- */
+
+ /* ----------------------------------------- */
+ /* SME SAPS */
+ /* ----------------------------------------- */
+ TR_STARTUP_SAP,
+ TR_SYS_SAP,
+ TR_MGT_SAP,
+ TR_DBG_SAP,
+ TR_BT_SAP,
+ /* ----------------------------------------- */
+
+ /* ----------------------------------------- */
+ /* SME PROCESSES / MODULES */
+ /* ----------------------------------------- */
+ TR_SCAN_STORAGE,
+ TR_CORE,
+ TR_CXN_MGR,
+ TR_SECURITY,
+ TR_MIB_ACCESS,
+ TR_SCAN,
+ TR_LINK_QUALITY,
+ TR_DBG,
+ TR_HIP_PROXY,
+ TR_MIB_ACCESS_FSM,
+ TR_NETWORK_SELECTOR_FSM,
+ TR_UNIFI_DRIVER_FSM,
+ TR_SME_CONFIGURATION_FSM,
+ TR_SME_MEASUREMENTS_FSM,
+ TR_POWER_MGR,
+ TR_COEX,
+ TR_CCX,
+ TR_DOT11N,
+ TR_REGDOM,
+ TR_QOS,
+ TR_CRYPTO_LIB,
+
+ /* ----------------------------------------- */
+
+ /* ----------------------------------------- */
+ /* FSM */
+ /* ----------------------------------------- */
+ TR_FSM,
+ TR_FSM_DUMP,
+ TR_MSC,
+ /* ----------------------------------------- */
+
+ /* ----------------------------------------- */
+ /* SECURITY LIBRARY */
+ /* ----------------------------------------- */
+ TR_SECURITY_LIB,
+ TR_SECURITY_WAPI,
+
+ /* ----------------------------------------- */
+ /* PAL */
+ /* ----------------------------------------- */
+#ifdef AMP_PAL_BUILD
+ TR_PAL_HCI_SAP,
+ TR_PAL_ACL_SAP,
+ TR_PAL_CTRL_SAP,
+ TR_PAL_UDT_SAP,
+ TR_PAL_MGR_FSM,
+ TR_PAL_LM_LINK_FSM,
+ TR_PAL_DM_FSM,
+ TR_PAL_DAM,
+ TR_PAL_LM_HIP_FSM,
+ TR_PAL_COEX_FSM,
+
+#endif
+ /* ----------------------------------------- */
+
+ TR_LAST_MODULE_ID
+} sme_trace_module_id;
+
+
+#ifdef SME_TRACE_ENABLE
+
+ extern void sme_trace_initialise(uint32 argc, char **argv);
+
+ extern void sme_trace_set_all_levels(sme_trace_level level);
+ extern void sme_trace_set_module_level(sme_trace_module_id id, sme_trace_level level);
+ extern sme_trace_level sme_trace_get_module_level(sme_trace_module_id id);
+ extern const char* sme_trace_module_to_str(sme_trace_module_id id);
+
+ /*
+ extern void sme_trace_fn(const char* name, const char* const format, ...);
+ #define sme_trace_msc(tracedata, args) if (tracedata->level > TR_LVL_INFO) { sme_trace_fn(tracedata->name, args); }
+ */
+
+ extern void sme_trace_msc_fn(sme_trace_module_id id, const char* const format, ...);
+ extern void sme_trace_entry_fn(sme_trace_module_id id, const char* const format, ...);
+ extern void sme_trace_debug_fn(sme_trace_module_id id, const char* const format, ...);
+ extern void sme_trace_info_fn(sme_trace_module_id id, const char* const format, ...);
+ extern void sme_trace_warn_fn(sme_trace_module_id id, const char* const format, ...);
+ extern void sme_trace_error_fn(sme_trace_module_id id, const char* const format, ...);
+ extern void sme_trace_crit_fn(sme_trace_module_id id, const char* const format, ...);
+ extern void sme_trace_hex_fn(sme_trace_module_id id, sme_trace_level level, const char* const message, const void* address, uint32 length);
+
+#else
+
+ #define sme_trace_initialise(argc, argv)
+
+ #define sme_trace_set_all_levels(level)
+ #define sme_trace_get_module_level(id) TR_LVL_OFF
+ #define sme_trace_set_module_level(id,level)
+ #define sme_trace_module_to_str(id) ""
+
+ #define SME_TRACE_NO_MSC
+ #define SME_TRACE_NO_ENTRY
+ #define SME_TRACE_NO_DEBUG
+ #define SME_TRACE_NO_INFO
+ #define SME_TRACE_NO_WARN
+ #define SME_TRACE_NO_ERROR
+ #define SME_TRACE_NO_CRIT
+ #define SME_TRACE_NO_HEX
+#endif
+
+
+#ifdef SME_TRACE_NO_MSC
+ #define sme_trace_msc(args)
+ #define sme_trace_msc_code(args)
+#else
+ #define sme_trace_msc(args) sme_trace_msc_fn args
+ #define sme_trace_msc_code(args) args
+#endif
+
+#ifdef SME_TRACE_NO_ENTRY
+ #define sme_trace_entry(args)
+ #define sme_trace_entry_code(args)
+#else
+ #define sme_trace_entry(args) sme_trace_entry_fn args
+ #define sme_trace_entry_code(args) args
+#endif
+
+#ifdef SME_TRACE_NO_DEBUG
+ #define sme_trace_debug(args)
+ #define sme_trace_debug_code(args)
+#else
+ #define sme_trace_debug(args) sme_trace_debug_fn args
+ #define sme_trace_debug_code(args) args
+#endif
+
+#ifdef SME_TRACE_NO_INFO
+ #define sme_trace_info(args)
+ #define sme_trace_info_code(args)
+#else
+ #define sme_trace_info(args) sme_trace_info_fn args
+ #define sme_trace_info_code(args) args
+#endif
+
+#ifdef SME_TRACE_NO_WARN
+ #define sme_trace_warn(args)
+ #define sme_trace_warn_code(args)
+#else
+ #define sme_trace_warn(args) sme_trace_warn_fn args
+ #define sme_trace_warn_code(args) args
+#endif
+
+#ifdef SME_TRACE_NO_ERROR
+ #define sme_trace_error(args)
+ #define sme_trace_error_code(args)
+#else
+ #define sme_trace_error(args) sme_trace_error_fn args
+ #define sme_trace_error_code(args) args
+#endif
+
+#ifdef SME_TRACE_NO_CRIT
+ #define sme_trace_crit(args)
+ #define sme_trace_crit_code(args)
+#else
+ #define sme_trace_crit(args) sme_trace_crit_fn args
+ #define sme_trace_crit_code(args) args
+#endif
+
+#ifdef SME_TRACE_NO_HEX
+ #define sme_trace_hex(args)
+ #define sme_trace_hex_code(args)
+#else
+ #define sme_trace_hex(args) sme_trace_hex_fn args
+ #define sme_trace_hex_code(args) args
+#endif
+
+#endif /* SME_TRACE_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_events.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_events.h
new file mode 100644
index 0000000..94b6a3a
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_events.h
@@ -0,0 +1,2150 @@
+/* This is an autogenerated file from from sme__fsm_signal_gen.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+/* This is an autogenerated file from sme___fsm_signal_gen.pl */
+
+
+#ifndef SME_SIGNALS_XML_SIGNALS_H
+#define SME_SIGNALS_XML_SIGNALS_H
+
+/* defines for BT_SIGNALS */
+
+#define UNIFI_BT_UNICORE_INIT_REQ_ID 0x7001
+#define UNIFI_BT_UNICORE_INIT_IND_ID 0x7002
+#define UNIFI_BT_UNICORE_FINAL_REQ_ID 0x7003
+#define UNIFI_BT_UNICORE_FINAL_IND_ID 0x7004
+#define UNIFI_BT_UNICORE_PING_REQ_ID 0x7005
+#define UNIFI_BT_UNICORE_PING_IND_ID 0x7006
+#define UNIFI_BT_UNICORE_PONG_REQ_ID 0x7007
+#define UNIFI_BT_UNICORE_PONG_IND_ID 0x7008
+#define UNIFI_BT_UNICORE_ACTIVE_DOT11_CHANNEL_REQ_ID 0x7009
+#define UNIFI_BT_UNICORE_PASS_SYNC_START_IND_ID 0x700A
+#define UNIFI_BT_UNICORE_PASS_SYNC_CHANGE_IND_ID 0x700B
+#define UNIFI_BT_UNICORE_PASS_SYNC_STOP_IND_ID 0x700C
+
+/* defines for DBG_SIGNALS */
+
+#define UNIFI_DBG_SET_ALL_LEVELS_REQ_ID 0x1900
+#define UNIFI_DBG_SET_LEVEL_REQ_ID 0x1901
+#define UNIFI_DBG_GET_LEVEL_REQ_ID 0x1902
+#define UNIFI_DBG_GET_LEVEL_CFM_ID 0x1903
+#define UNIFI_DBG_EXIT_REQ_ID 0x1904
+#define UNIFI_DBG_CMD_REQ_ID 0x1905
+
+/* defines for MGT_SIGNALS */
+
+#define UNIFI_MGT_WIFI_ON_REQ_ID 0x9001
+#define UNIFI_MGT_WIFI_ON_CFM_ID 0x9002
+#define UNIFI_MGT_WIFI_OFF_REQ_ID 0x9003
+#define UNIFI_MGT_WIFI_OFF_CFM_ID 0x9004
+#define UNIFI_MGT_WIFI_OFF_IND_ID 0x9005
+#define UNIFI_MGT_WIFI_FLIGHTMODE_REQ_ID 0x9006
+#define UNIFI_MGT_WIFI_FLIGHTMODE_CFM_ID 0x9007
+#define UNIFI_MGT_SET_VALUE_REQ_ID 0x9008
+#define UNIFI_MGT_SET_VALUE_CFM_ID 0x9009
+#define UNIFI_MGT_GET_VALUE_REQ_ID 0x900A
+#define UNIFI_MGT_GET_VALUE_CFM_ID 0x900B
+#define UNIFI_MGT_MIB_SET_REQ_ID 0x900C
+#define UNIFI_MGT_MIB_SET_CFM_ID 0x900D
+#define UNIFI_MGT_MIB_GET_REQ_ID 0x900E
+#define UNIFI_MGT_MIB_GET_CFM_ID 0x900F
+#define UNIFI_MGT_MIB_GET_NEXT_REQ_ID 0x9010
+#define UNIFI_MGT_MIB_GET_NEXT_CFM_ID 0x9011
+#define UNIFI_MGT_SCAN_FULL_REQ_ID 0x9012
+#define UNIFI_MGT_SCAN_FULL_CFM_ID 0x9013
+#define UNIFI_MGT_SCAN_RESULTS_GET_REQ_ID 0x9014
+#define UNIFI_MGT_SCAN_RESULTS_GET_CFM_ID 0x9015
+#define UNIFI_MGT_SCAN_RESULT_IND_ID 0x9016
+#define UNIFI_MGT_CONNECT_REQ_ID 0x9017
+#define UNIFI_MGT_CONNECT_CFM_ID 0x9018
+#define UNIFI_MGT_MEDIA_STATUS_IND_ID 0x9019
+#define UNIFI_MGT_CONNECTION_QUALITY_IND_ID 0x901A
+#define UNIFI_MGT_DISCONNECT_REQ_ID 0x901B
+#define UNIFI_MGT_DISCONNECT_CFM_ID 0x901C
+#define UNIFI_MGT_MULTICAST_ADDRESS_REQ_ID 0x901D
+#define UNIFI_MGT_MULTICAST_ADDRESS_CFM_ID 0x901E
+#define UNIFI_MGT_MIC_FAILURE_IND_ID 0x901F
+#define UNIFI_MGT_PMKID_CANDIDATE_LIST_IND_ID 0x9020
+#define UNIFI_MGT_PMKID_REQ_ID 0x9021
+#define UNIFI_MGT_PMKID_CFM_ID 0x9022
+#define UNIFI_MGT_KEY_REQ_ID 0x9023
+#define UNIFI_MGT_KEY_CFM_ID 0x9024
+#define UNIFI_MGT_PACKET_FILTER_SET_REQ_ID 0x9025
+#define UNIFI_MGT_PACKET_FILTER_SET_CFM_ID 0x9026
+#define UNIFI_MGT_TSPEC_REQ_ID 0x9027
+#define UNIFI_MGT_TSPEC_CFM_ID 0x9028
+#define UNIFI_MGT_TSPEC_IND_ID 0x9029
+
+/* defines for SYS_SIGNALS */
+
+#define UNIFI_SYS_WIFI_ON_REQ_ID 0x8001
+#define UNIFI_SYS_WIFI_ON_IND_ID 0x8002
+#define UNIFI_SYS_WIFI_ON_RSP_ID 0x8003
+#define UNIFI_SYS_WIFI_ON_CFM_ID 0x8004
+#define UNIFI_SYS_WIFI_OFF_REQ_ID 0x8005
+#define UNIFI_SYS_WIFI_OFF_IND_ID 0x8006
+#define UNIFI_SYS_WIFI_OFF_RSP_ID 0x8007
+#define UNIFI_SYS_WIFI_OFF_CFM_ID 0x8008
+#define UNIFI_SYS_SUSPEND_IND_ID 0x8009
+#define UNIFI_SYS_SUSPEND_RSP_ID 0x800A
+#define UNIFI_SYS_RESUME_IND_ID 0x800B
+#define UNIFI_SYS_RESUME_RSP_ID 0x800C
+#define UNIFI_SYS_HIP_REQ_ID 0x800D
+#define UNIFI_SYS_HIP_IND_ID 0x800E
+#define UNIFI_SYS_QOS_CONTROL_REQ_ID 0x800F
+#define UNIFI_SYS_QOS_CONTROL_CFM_ID 0x8010
+#define UNIFI_SYS_PORT_CONFIGURE_REQ_ID 0x8011
+#define UNIFI_SYS_PORT_CONFIGURE_CFM_ID 0x8012
+#define UNIFI_SYS_CONFIGURE_POWER_MODE_REQ_ID 0x8013
+#define UNIFI_SYS_TRAFFIC_CONFIG_REQ_ID 0x8014
+#define UNIFI_SYS_TRAFFIC_SAMPLE_IND_ID 0x8015
+#define UNIFI_SYS_TRAFFIC_PROTOCOL_IND_ID 0x8016
+#define UNIFI_SYS_IP_CONFIGURED_IND_ID 0x8017
+#define UNIFI_SYS_MEDIA_STATUS_REQ_ID 0x8018
+#define UNIFI_SYS_MULTICAST_ADDRESS_IND_ID 0x8019
+#define UNIFI_SYS_MULTICAST_ADDRESS_RSP_ID 0x801A
+#define UNIFI_SYS_TCLAS_ADD_REQ_ID 0x801B
+#define UNIFI_SYS_TCLAS_ADD_CFM_ID 0x801C
+#define UNIFI_SYS_TCLAS_DEL_REQ_ID 0x801D
+#define UNIFI_SYS_TCLAS_DEL_CFM_ID 0x801E
+#define UNIFI_SYS_TRAFFIC_CLASSIFICATION_REQ_ID 0x801F
+
+/* -------------------------- UNIFI_BT_UNICORE_INIT.request -------------------------- */
+typedef struct UnifiBtUnicoreInitReq_Evt
+{
+ FsmEvent common;
+ uint16 minVersion;
+ uint16 maxVersion;
+ Boolean reply;
+} UnifiBtUnicoreInitReq_Evt;
+
+#define send_unifi_bt_unicore_init_req(context, pid, p1_minVersion, p2_maxVersion, p3_reply) \
+{ \
+ UnifiBtUnicoreInitReq_Evt *evt = (UnifiBtUnicoreInitReq_Evt*) osa_malloc(sizeof(UnifiBtUnicoreInitReq_Evt));\
+ evt->minVersion = p1_minVersion;\
+ evt->maxVersion = p2_maxVersion;\
+ evt->reply = p3_reply;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_INIT_REQ_ID);\
+}
+
+#define send_unifi_bt_unicore_init_req_external(context, pid, p1_minVersion, p2_maxVersion, p3_reply) \
+{ \
+ UnifiBtUnicoreInitReq_Evt *evt = (UnifiBtUnicoreInitReq_Evt*) osa_malloc(sizeof(UnifiBtUnicoreInitReq_Evt));\
+ evt->minVersion = p1_minVersion;\
+ evt->maxVersion = p2_maxVersion;\
+ evt->reply = p3_reply;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_INIT_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_INIT.indication -------------------------- */
+typedef struct UnifiBtUnicoreInitInd_Evt
+{
+ FsmEvent common;
+ uint16 minVersion;
+ uint16 maxVersion;
+ Boolean reply;
+} UnifiBtUnicoreInitInd_Evt;
+
+#define send_unifi_bt_unicore_init_ind(context, pid, p1_minVersion, p2_maxVersion, p3_reply) \
+{ \
+ UnifiBtUnicoreInitInd_Evt *evt = (UnifiBtUnicoreInitInd_Evt*) osa_malloc(sizeof(UnifiBtUnicoreInitInd_Evt));\
+ evt->minVersion = p1_minVersion;\
+ evt->maxVersion = p2_maxVersion;\
+ evt->reply = p3_reply;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_INIT_IND_ID);\
+}
+
+#define send_unifi_bt_unicore_init_ind_external(context, pid, p1_minVersion, p2_maxVersion, p3_reply) \
+{ \
+ UnifiBtUnicoreInitInd_Evt *evt = (UnifiBtUnicoreInitInd_Evt*) osa_malloc(sizeof(UnifiBtUnicoreInitInd_Evt));\
+ evt->minVersion = p1_minVersion;\
+ evt->maxVersion = p2_maxVersion;\
+ evt->reply = p3_reply;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_INIT_IND_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_FINAL.request -------------------------- */
+typedef struct UnifiBtUnicoreFinalReq_Evt
+{
+ FsmEvent common;
+} UnifiBtUnicoreFinalReq_Evt;
+
+#define send_unifi_bt_unicore_final_req(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_BT_UNICORE_FINAL_REQ_ID);\
+}
+
+#define send_unifi_bt_unicore_final_req_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_BT_UNICORE_FINAL_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_FINAL.indication -------------------------- */
+typedef struct UnifiBtUnicoreFinalInd_Evt
+{
+ FsmEvent common;
+} UnifiBtUnicoreFinalInd_Evt;
+
+#define send_unifi_bt_unicore_final_ind(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_BT_UNICORE_FINAL_IND_ID);\
+}
+
+#define send_unifi_bt_unicore_final_ind_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_BT_UNICORE_FINAL_IND_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_PING.request -------------------------- */
+typedef struct UnifiBtUnicorePingReq_Evt
+{
+ FsmEvent common;
+ uint16 tag;
+} UnifiBtUnicorePingReq_Evt;
+
+#define send_unifi_bt_unicore_ping_req(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePingReq_Evt *evt = (UnifiBtUnicorePingReq_Evt*) osa_malloc(sizeof(UnifiBtUnicorePingReq_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PING_REQ_ID);\
+}
+
+#define send_unifi_bt_unicore_ping_req_external(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePingReq_Evt *evt = (UnifiBtUnicorePingReq_Evt*) osa_malloc(sizeof(UnifiBtUnicorePingReq_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PING_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_PING.indication -------------------------- */
+typedef struct UnifiBtUnicorePingInd_Evt
+{
+ FsmEvent common;
+ uint16 tag;
+} UnifiBtUnicorePingInd_Evt;
+
+#define send_unifi_bt_unicore_ping_ind(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePingInd_Evt *evt = (UnifiBtUnicorePingInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePingInd_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PING_IND_ID);\
+}
+
+#define send_unifi_bt_unicore_ping_ind_external(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePingInd_Evt *evt = (UnifiBtUnicorePingInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePingInd_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PING_IND_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_PONG.request -------------------------- */
+typedef struct UnifiBtUnicorePongReq_Evt
+{
+ FsmEvent common;
+ uint16 tag;
+} UnifiBtUnicorePongReq_Evt;
+
+#define send_unifi_bt_unicore_pong_req(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePongReq_Evt *evt = (UnifiBtUnicorePongReq_Evt*) osa_malloc(sizeof(UnifiBtUnicorePongReq_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PONG_REQ_ID);\
+}
+
+#define send_unifi_bt_unicore_pong_req_external(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePongReq_Evt *evt = (UnifiBtUnicorePongReq_Evt*) osa_malloc(sizeof(UnifiBtUnicorePongReq_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PONG_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_PONG.indication -------------------------- */
+typedef struct UnifiBtUnicorePongInd_Evt
+{
+ FsmEvent common;
+ uint16 tag;
+} UnifiBtUnicorePongInd_Evt;
+
+#define send_unifi_bt_unicore_pong_ind(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePongInd_Evt *evt = (UnifiBtUnicorePongInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePongInd_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PONG_IND_ID);\
+}
+
+#define send_unifi_bt_unicore_pong_ind_external(context, pid, p1_tag) \
+{ \
+ UnifiBtUnicorePongInd_Evt *evt = (UnifiBtUnicorePongInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePongInd_Evt));\
+ evt->tag = p1_tag;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PONG_IND_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_ACTIVE_DOT11_CHANNEL.request -------------------------- */
+typedef struct UnifiBtUnicoreActiveDot11ChannelReq_Evt
+{
+ FsmEvent common;
+ uint16 channelMhz;
+ uint16 bandwidthMhz;
+} UnifiBtUnicoreActiveDot11ChannelReq_Evt;
+
+#define send_unifi_bt_unicore_active_dot11_channel_req(context, pid, p1_channelMhz, p2_bandwidthMhz) \
+{ \
+ UnifiBtUnicoreActiveDot11ChannelReq_Evt *evt = (UnifiBtUnicoreActiveDot11ChannelReq_Evt*) osa_malloc(sizeof(UnifiBtUnicoreActiveDot11ChannelReq_Evt));\
+ evt->channelMhz = p1_channelMhz;\
+ evt->bandwidthMhz = p2_bandwidthMhz;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_ACTIVE_DOT11_CHANNEL_REQ_ID);\
+}
+
+#define send_unifi_bt_unicore_active_dot11_channel_req_external(context, pid, p1_channelMhz, p2_bandwidthMhz) \
+{ \
+ UnifiBtUnicoreActiveDot11ChannelReq_Evt *evt = (UnifiBtUnicoreActiveDot11ChannelReq_Evt*) osa_malloc(sizeof(UnifiBtUnicoreActiveDot11ChannelReq_Evt));\
+ evt->channelMhz = p1_channelMhz;\
+ evt->bandwidthMhz = p2_bandwidthMhz;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_ACTIVE_DOT11_CHANNEL_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_PASS_SYNC_START.indication -------------------------- */
+typedef struct UnifiBtUnicorePassSyncStartInd_Evt
+{
+ FsmEvent common;
+ uint16 connectionHandle;
+ uint16 period;
+ uint16 durationMin;
+ uint16 durationMax;
+} UnifiBtUnicorePassSyncStartInd_Evt;
+
+#define send_unifi_bt_unicore_pass_sync_start_ind(context, pid, p1_connectionHandle, p2_period, p3_durationMin, p4_durationMax) \
+{ \
+ UnifiBtUnicorePassSyncStartInd_Evt *evt = (UnifiBtUnicorePassSyncStartInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePassSyncStartInd_Evt));\
+ evt->connectionHandle = p1_connectionHandle;\
+ evt->period = p2_period;\
+ evt->durationMin = p3_durationMin;\
+ evt->durationMax = p4_durationMax;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PASS_SYNC_START_IND_ID);\
+}
+
+#define send_unifi_bt_unicore_pass_sync_start_ind_external(context, pid, p1_connectionHandle, p2_period, p3_durationMin, p4_durationMax) \
+{ \
+ UnifiBtUnicorePassSyncStartInd_Evt *evt = (UnifiBtUnicorePassSyncStartInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePassSyncStartInd_Evt));\
+ evt->connectionHandle = p1_connectionHandle;\
+ evt->period = p2_period;\
+ evt->durationMin = p3_durationMin;\
+ evt->durationMax = p4_durationMax;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PASS_SYNC_START_IND_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_PASS_SYNC_CHANGE.indication -------------------------- */
+typedef struct UnifiBtUnicorePassSyncChangeInd_Evt
+{
+ FsmEvent common;
+ uint16 connectionHandle;
+ uint16 period;
+ uint16 durationMin;
+ uint16 durationMax;
+} UnifiBtUnicorePassSyncChangeInd_Evt;
+
+#define send_unifi_bt_unicore_pass_sync_change_ind(context, pid, p1_connectionHandle, p2_period, p3_durationMin, p4_durationMax) \
+{ \
+ UnifiBtUnicorePassSyncChangeInd_Evt *evt = (UnifiBtUnicorePassSyncChangeInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePassSyncChangeInd_Evt));\
+ evt->connectionHandle = p1_connectionHandle;\
+ evt->period = p2_period;\
+ evt->durationMin = p3_durationMin;\
+ evt->durationMax = p4_durationMax;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PASS_SYNC_CHANGE_IND_ID);\
+}
+
+#define send_unifi_bt_unicore_pass_sync_change_ind_external(context, pid, p1_connectionHandle, p2_period, p3_durationMin, p4_durationMax) \
+{ \
+ UnifiBtUnicorePassSyncChangeInd_Evt *evt = (UnifiBtUnicorePassSyncChangeInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePassSyncChangeInd_Evt));\
+ evt->connectionHandle = p1_connectionHandle;\
+ evt->period = p2_period;\
+ evt->durationMin = p3_durationMin;\
+ evt->durationMax = p4_durationMax;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PASS_SYNC_CHANGE_IND_ID);\
+}
+
+/* -------------------------- UNIFI_BT_UNICORE_PASS_SYNC_STOP.indication -------------------------- */
+typedef struct UnifiBtUnicorePassSyncStopInd_Evt
+{
+ FsmEvent common;
+ uint16 connectionHandle;
+} UnifiBtUnicorePassSyncStopInd_Evt;
+
+#define send_unifi_bt_unicore_pass_sync_stop_ind(context, pid, p1_connectionHandle) \
+{ \
+ UnifiBtUnicorePassSyncStopInd_Evt *evt = (UnifiBtUnicorePassSyncStopInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePassSyncStopInd_Evt));\
+ evt->connectionHandle = p1_connectionHandle;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PASS_SYNC_STOP_IND_ID);\
+}
+
+#define send_unifi_bt_unicore_pass_sync_stop_ind_external(context, pid, p1_connectionHandle) \
+{ \
+ UnifiBtUnicorePassSyncStopInd_Evt *evt = (UnifiBtUnicorePassSyncStopInd_Evt*) osa_malloc(sizeof(UnifiBtUnicorePassSyncStopInd_Evt));\
+ evt->connectionHandle = p1_connectionHandle;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_BT_UNICORE_PASS_SYNC_STOP_IND_ID);\
+}
+
+/* -------------------------- UNIFI_DBG_SET_ALL_LEVELS.request -------------------------- */
+typedef struct UnifiDbgSetAllLevelsReq_Evt
+{
+ FsmEvent common;
+ uint16 level;
+} UnifiDbgSetAllLevelsReq_Evt;
+
+#define send_unifi_dbg_set_all_levels_req(context, pid, p1_level) \
+{ \
+ UnifiDbgSetAllLevelsReq_Evt *evt = (UnifiDbgSetAllLevelsReq_Evt*) osa_malloc(sizeof(UnifiDbgSetAllLevelsReq_Evt));\
+ evt->level = p1_level;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_DBG_SET_ALL_LEVELS_REQ_ID);\
+}
+
+#define send_unifi_dbg_set_all_levels_req_external(context, pid, p1_level) \
+{ \
+ UnifiDbgSetAllLevelsReq_Evt *evt = (UnifiDbgSetAllLevelsReq_Evt*) osa_malloc(sizeof(UnifiDbgSetAllLevelsReq_Evt));\
+ evt->level = p1_level;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_DBG_SET_ALL_LEVELS_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_DBG_SET_LEVEL.request -------------------------- */
+typedef struct UnifiDbgSetLevelReq_Evt
+{
+ FsmEvent common;
+ uint16 id;
+ uint16 level;
+} UnifiDbgSetLevelReq_Evt;
+
+#define send_unifi_dbg_set_level_req(context, pid, p1_id, p2_level) \
+{ \
+ UnifiDbgSetLevelReq_Evt *evt = (UnifiDbgSetLevelReq_Evt*) osa_malloc(sizeof(UnifiDbgSetLevelReq_Evt));\
+ evt->id = p1_id;\
+ evt->level = p2_level;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_DBG_SET_LEVEL_REQ_ID);\
+}
+
+#define send_unifi_dbg_set_level_req_external(context, pid, p1_id, p2_level) \
+{ \
+ UnifiDbgSetLevelReq_Evt *evt = (UnifiDbgSetLevelReq_Evt*) osa_malloc(sizeof(UnifiDbgSetLevelReq_Evt));\
+ evt->id = p1_id;\
+ evt->level = p2_level;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_DBG_SET_LEVEL_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_DBG_GET_LEVEL.request -------------------------- */
+typedef struct UnifiDbgGetLevelReq_Evt
+{
+ FsmEvent common;
+ uint16 id;
+} UnifiDbgGetLevelReq_Evt;
+
+#define send_unifi_dbg_get_level_req(context, pid, p1_id) \
+{ \
+ UnifiDbgGetLevelReq_Evt *evt = (UnifiDbgGetLevelReq_Evt*) osa_malloc(sizeof(UnifiDbgGetLevelReq_Evt));\
+ evt->id = p1_id;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_DBG_GET_LEVEL_REQ_ID);\
+}
+
+#define send_unifi_dbg_get_level_req_external(context, pid, p1_id) \
+{ \
+ UnifiDbgGetLevelReq_Evt *evt = (UnifiDbgGetLevelReq_Evt*) osa_malloc(sizeof(UnifiDbgGetLevelReq_Evt));\
+ evt->id = p1_id;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_DBG_GET_LEVEL_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_DBG_GET_LEVEL.confirm -------------------------- */
+typedef struct UnifiDbgGetLevelCfm_Evt
+{
+ FsmEvent common;
+ uint16 id;
+ uint16 level;
+} UnifiDbgGetLevelCfm_Evt;
+
+#define send_unifi_dbg_get_level_cfm(context, pid, p1_id, p2_level) \
+{ \
+ UnifiDbgGetLevelCfm_Evt *evt = (UnifiDbgGetLevelCfm_Evt*) osa_malloc(sizeof(UnifiDbgGetLevelCfm_Evt));\
+ evt->id = p1_id;\
+ evt->level = p2_level;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_DBG_GET_LEVEL_CFM_ID);\
+}
+
+#define send_unifi_dbg_get_level_cfm_external(context, pid, p1_id, p2_level) \
+{ \
+ UnifiDbgGetLevelCfm_Evt *evt = (UnifiDbgGetLevelCfm_Evt*) osa_malloc(sizeof(UnifiDbgGetLevelCfm_Evt));\
+ evt->id = p1_id;\
+ evt->level = p2_level;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_DBG_GET_LEVEL_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_DBG_EXIT.request -------------------------- */
+typedef struct UnifiDbgExitReq_Evt
+{
+ FsmEvent common;
+} UnifiDbgExitReq_Evt;
+
+#define send_unifi_dbg_exit_req(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_DBG_EXIT_REQ_ID);\
+}
+
+#define send_unifi_dbg_exit_req_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_DBG_EXIT_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_DBG_CMD.request -------------------------- */
+typedef struct UnifiDbgCmdReq_Evt
+{
+ FsmEvent common;
+ unifi_String command;
+} UnifiDbgCmdReq_Evt;
+
+#define send_unifi_dbg_cmd_req(context, pid, p1_command) \
+{ \
+ UnifiDbgCmdReq_Evt *evt = (UnifiDbgCmdReq_Evt*) osa_malloc(sizeof(UnifiDbgCmdReq_Evt));\
+ evt->command = p1_command;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_DBG_CMD_REQ_ID);\
+}
+
+#define send_unifi_dbg_cmd_req_external(context, pid, p1_command) \
+{ \
+ UnifiDbgCmdReq_Evt *evt = (UnifiDbgCmdReq_Evt*) osa_malloc(sizeof(UnifiDbgCmdReq_Evt));\
+ evt->command = p1_command;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_DBG_CMD_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_WIFI_ON.request -------------------------- */
+typedef struct UnifiMgtWifiOnReq_Evt
+{
+ FsmEvent common;
+ unifi_MACAddress address;
+ unifi_DataBlockList mibFiles;
+} UnifiMgtWifiOnReq_Evt;
+
+#define send_unifi_mgt_wifi_on_req(context, pid, p1_address, p2_mibFiles) \
+{ \
+ UnifiMgtWifiOnReq_Evt *evt = (UnifiMgtWifiOnReq_Evt*) osa_malloc(sizeof(UnifiMgtWifiOnReq_Evt));\
+ evt->address = p1_address;\
+ evt->mibFiles = p2_mibFiles;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_ON_REQ_ID);\
+}
+
+#define send_unifi_mgt_wifi_on_req_external(context, pid, p1_address, p2_mibFiles) \
+{ \
+ UnifiMgtWifiOnReq_Evt *evt = (UnifiMgtWifiOnReq_Evt*) osa_malloc(sizeof(UnifiMgtWifiOnReq_Evt));\
+ evt->address = p1_address;\
+ evt->mibFiles = p2_mibFiles;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_ON_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_WIFI_ON.confirm -------------------------- */
+typedef struct UnifiMgtWifiOnCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtWifiOnCfm_Evt;
+
+#define send_unifi_mgt_wifi_on_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtWifiOnCfm_Evt *evt = (UnifiMgtWifiOnCfm_Evt*) osa_malloc(sizeof(UnifiMgtWifiOnCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_ON_CFM_ID);\
+}
+
+#define send_unifi_mgt_wifi_on_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtWifiOnCfm_Evt *evt = (UnifiMgtWifiOnCfm_Evt*) osa_malloc(sizeof(UnifiMgtWifiOnCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_ON_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_WIFI_OFF.request -------------------------- */
+typedef struct UnifiMgtWifiOffReq_Evt
+{
+ FsmEvent common;
+} UnifiMgtWifiOffReq_Evt;
+
+#define send_unifi_mgt_wifi_off_req(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_MGT_WIFI_OFF_REQ_ID);\
+}
+
+#define send_unifi_mgt_wifi_off_req_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_MGT_WIFI_OFF_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_WIFI_OFF.confirm -------------------------- */
+typedef struct UnifiMgtWifiOffCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtWifiOffCfm_Evt;
+
+#define send_unifi_mgt_wifi_off_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtWifiOffCfm_Evt *evt = (UnifiMgtWifiOffCfm_Evt*) osa_malloc(sizeof(UnifiMgtWifiOffCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_OFF_CFM_ID);\
+}
+
+#define send_unifi_mgt_wifi_off_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtWifiOffCfm_Evt *evt = (UnifiMgtWifiOffCfm_Evt*) osa_malloc(sizeof(UnifiMgtWifiOffCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_OFF_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_WIFI_OFF.indication -------------------------- */
+typedef struct UnifiMgtWifiOffInd_Evt
+{
+ FsmEvent common;
+ unifi_ControlIndication controlIndication;
+} UnifiMgtWifiOffInd_Evt;
+
+#define send_unifi_mgt_wifi_off_ind(context, pid, p1_controlIndication) \
+{ \
+ UnifiMgtWifiOffInd_Evt *evt = (UnifiMgtWifiOffInd_Evt*) osa_malloc(sizeof(UnifiMgtWifiOffInd_Evt));\
+ evt->controlIndication = p1_controlIndication;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_OFF_IND_ID);\
+}
+
+#define send_unifi_mgt_wifi_off_ind_external(context, pid, p1_controlIndication) \
+{ \
+ UnifiMgtWifiOffInd_Evt *evt = (UnifiMgtWifiOffInd_Evt*) osa_malloc(sizeof(UnifiMgtWifiOffInd_Evt));\
+ evt->controlIndication = p1_controlIndication;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_OFF_IND_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_WIFI_FLIGHTMODE.request -------------------------- */
+typedef struct UnifiMgtWifiFlightmodeReq_Evt
+{
+ FsmEvent common;
+ unifi_MACAddress address;
+ unifi_DataBlockList mibFiles;
+} UnifiMgtWifiFlightmodeReq_Evt;
+
+#define send_unifi_mgt_wifi_flightmode_req(context, pid, p1_address, p2_mibFiles) \
+{ \
+ UnifiMgtWifiFlightmodeReq_Evt *evt = (UnifiMgtWifiFlightmodeReq_Evt*) osa_malloc(sizeof(UnifiMgtWifiFlightmodeReq_Evt));\
+ evt->address = p1_address;\
+ evt->mibFiles = p2_mibFiles;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_FLIGHTMODE_REQ_ID);\
+}
+
+#define send_unifi_mgt_wifi_flightmode_req_external(context, pid, p1_address, p2_mibFiles) \
+{ \
+ UnifiMgtWifiFlightmodeReq_Evt *evt = (UnifiMgtWifiFlightmodeReq_Evt*) osa_malloc(sizeof(UnifiMgtWifiFlightmodeReq_Evt));\
+ evt->address = p1_address;\
+ evt->mibFiles = p2_mibFiles;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_FLIGHTMODE_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_WIFI_FLIGHTMODE.confirm -------------------------- */
+typedef struct UnifiMgtWifiFlightmodeCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtWifiFlightmodeCfm_Evt;
+
+#define send_unifi_mgt_wifi_flightmode_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtWifiFlightmodeCfm_Evt *evt = (UnifiMgtWifiFlightmodeCfm_Evt*) osa_malloc(sizeof(UnifiMgtWifiFlightmodeCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_FLIGHTMODE_CFM_ID);\
+}
+
+#define send_unifi_mgt_wifi_flightmode_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtWifiFlightmodeCfm_Evt *evt = (UnifiMgtWifiFlightmodeCfm_Evt*) osa_malloc(sizeof(UnifiMgtWifiFlightmodeCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_WIFI_FLIGHTMODE_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_SET_VALUE.request -------------------------- */
+typedef struct UnifiMgtSetValueReq_Evt
+{
+ FsmEvent common;
+ unifi_AppValue appValue;
+} UnifiMgtSetValueReq_Evt;
+
+#define send_unifi_mgt_set_value_req(context, pid, p1_appValue) \
+{ \
+ UnifiMgtSetValueReq_Evt *evt = (UnifiMgtSetValueReq_Evt*) osa_malloc(sizeof(UnifiMgtSetValueReq_Evt));\
+ evt->appValue = p1_appValue;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_SET_VALUE_REQ_ID);\
+}
+
+#define send_unifi_mgt_set_value_req_external(context, pid, p1_appValue) \
+{ \
+ UnifiMgtSetValueReq_Evt *evt = (UnifiMgtSetValueReq_Evt*) osa_malloc(sizeof(UnifiMgtSetValueReq_Evt));\
+ evt->appValue = p1_appValue;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_SET_VALUE_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_SET_VALUE.confirm -------------------------- */
+typedef struct UnifiMgtSetValueCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_AppValueId appValueId;
+} UnifiMgtSetValueCfm_Evt;
+
+#define send_unifi_mgt_set_value_cfm(context, pid, p1_status, p2_appValueId) \
+{ \
+ UnifiMgtSetValueCfm_Evt *evt = (UnifiMgtSetValueCfm_Evt*) osa_malloc(sizeof(UnifiMgtSetValueCfm_Evt));\
+ evt->status = p1_status;\
+ evt->appValueId = p2_appValueId;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_SET_VALUE_CFM_ID);\
+}
+
+#define send_unifi_mgt_set_value_cfm_external(context, pid, p1_status, p2_appValueId) \
+{ \
+ UnifiMgtSetValueCfm_Evt *evt = (UnifiMgtSetValueCfm_Evt*) osa_malloc(sizeof(UnifiMgtSetValueCfm_Evt));\
+ evt->status = p1_status;\
+ evt->appValueId = p2_appValueId;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_SET_VALUE_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_GET_VALUE.request -------------------------- */
+typedef struct UnifiMgtGetValueReq_Evt
+{
+ FsmEvent common;
+ unifi_AppValueId appValueId;
+} UnifiMgtGetValueReq_Evt;
+
+#define send_unifi_mgt_get_value_req(context, pid, p1_appValueId) \
+{ \
+ UnifiMgtGetValueReq_Evt *evt = (UnifiMgtGetValueReq_Evt*) osa_malloc(sizeof(UnifiMgtGetValueReq_Evt));\
+ evt->appValueId = p1_appValueId;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_GET_VALUE_REQ_ID);\
+}
+
+#define send_unifi_mgt_get_value_req_external(context, pid, p1_appValueId) \
+{ \
+ UnifiMgtGetValueReq_Evt *evt = (UnifiMgtGetValueReq_Evt*) osa_malloc(sizeof(UnifiMgtGetValueReq_Evt));\
+ evt->appValueId = p1_appValueId;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_GET_VALUE_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_GET_VALUE.confirm -------------------------- */
+typedef struct UnifiMgtGetValueCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_AppValue appValue;
+} UnifiMgtGetValueCfm_Evt;
+
+#define send_unifi_mgt_get_value_cfm(context, pid, p1_status, p2_appValue) \
+{ \
+ UnifiMgtGetValueCfm_Evt *evt = (UnifiMgtGetValueCfm_Evt*) osa_malloc(sizeof(UnifiMgtGetValueCfm_Evt));\
+ evt->status = p1_status;\
+ evt->appValue = p2_appValue;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_GET_VALUE_CFM_ID);\
+}
+
+#define send_unifi_mgt_get_value_cfm_external(context, pid, p1_status, p2_appValue) \
+{ \
+ UnifiMgtGetValueCfm_Evt *evt = (UnifiMgtGetValueCfm_Evt*) osa_malloc(sizeof(UnifiMgtGetValueCfm_Evt));\
+ evt->status = p1_status;\
+ evt->appValue = p2_appValue;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_GET_VALUE_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MIB_SET.request -------------------------- */
+typedef struct UnifiMgtMibSetReq_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock mibAttribute;
+} UnifiMgtMibSetReq_Evt;
+
+#define send_unifi_mgt_mib_set_req(context, pid, p1_mibAttribute) \
+{ \
+ UnifiMgtMibSetReq_Evt *evt = (UnifiMgtMibSetReq_Evt*) osa_malloc(sizeof(UnifiMgtMibSetReq_Evt));\
+ evt->mibAttribute = p1_mibAttribute;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_SET_REQ_ID);\
+}
+
+#define send_unifi_mgt_mib_set_req_external(context, pid, p1_mibAttribute) \
+{ \
+ UnifiMgtMibSetReq_Evt *evt = (UnifiMgtMibSetReq_Evt*) osa_malloc(sizeof(UnifiMgtMibSetReq_Evt));\
+ evt->mibAttribute = p1_mibAttribute;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_SET_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MIB_SET.confirm -------------------------- */
+typedef struct UnifiMgtMibSetCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtMibSetCfm_Evt;
+
+#define send_unifi_mgt_mib_set_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtMibSetCfm_Evt *evt = (UnifiMgtMibSetCfm_Evt*) osa_malloc(sizeof(UnifiMgtMibSetCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_SET_CFM_ID);\
+}
+
+#define send_unifi_mgt_mib_set_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtMibSetCfm_Evt *evt = (UnifiMgtMibSetCfm_Evt*) osa_malloc(sizeof(UnifiMgtMibSetCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_SET_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MIB_GET.request -------------------------- */
+typedef struct UnifiMgtMibGetReq_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock mibAttribute;
+} UnifiMgtMibGetReq_Evt;
+
+#define send_unifi_mgt_mib_get_req(context, pid, p1_mibAttribute) \
+{ \
+ UnifiMgtMibGetReq_Evt *evt = (UnifiMgtMibGetReq_Evt*) osa_malloc(sizeof(UnifiMgtMibGetReq_Evt));\
+ evt->mibAttribute = p1_mibAttribute;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_REQ_ID);\
+}
+
+#define send_unifi_mgt_mib_get_req_external(context, pid, p1_mibAttribute) \
+{ \
+ UnifiMgtMibGetReq_Evt *evt = (UnifiMgtMibGetReq_Evt*) osa_malloc(sizeof(UnifiMgtMibGetReq_Evt));\
+ evt->mibAttribute = p1_mibAttribute;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MIB_GET.confirm -------------------------- */
+typedef struct UnifiMgtMibGetCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_DataBlock mibAttributeValue;
+} UnifiMgtMibGetCfm_Evt;
+
+#define send_unifi_mgt_mib_get_cfm(context, pid, p1_status, p2_mibAttributeValue) \
+{ \
+ UnifiMgtMibGetCfm_Evt *evt = (UnifiMgtMibGetCfm_Evt*) osa_malloc(sizeof(UnifiMgtMibGetCfm_Evt));\
+ evt->status = p1_status;\
+ evt->mibAttributeValue = p2_mibAttributeValue;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_CFM_ID);\
+}
+
+#define send_unifi_mgt_mib_get_cfm_external(context, pid, p1_status, p2_mibAttributeValue) \
+{ \
+ UnifiMgtMibGetCfm_Evt *evt = (UnifiMgtMibGetCfm_Evt*) osa_malloc(sizeof(UnifiMgtMibGetCfm_Evt));\
+ evt->status = p1_status;\
+ evt->mibAttributeValue = p2_mibAttributeValue;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MIB_GET_NEXT.request -------------------------- */
+typedef struct UnifiMgtMibGetNextReq_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock mibAttribute;
+} UnifiMgtMibGetNextReq_Evt;
+
+#define send_unifi_mgt_mib_get_next_req(context, pid, p1_mibAttribute) \
+{ \
+ UnifiMgtMibGetNextReq_Evt *evt = (UnifiMgtMibGetNextReq_Evt*) osa_malloc(sizeof(UnifiMgtMibGetNextReq_Evt));\
+ evt->mibAttribute = p1_mibAttribute;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_NEXT_REQ_ID);\
+}
+
+#define send_unifi_mgt_mib_get_next_req_external(context, pid, p1_mibAttribute) \
+{ \
+ UnifiMgtMibGetNextReq_Evt *evt = (UnifiMgtMibGetNextReq_Evt*) osa_malloc(sizeof(UnifiMgtMibGetNextReq_Evt));\
+ evt->mibAttribute = p1_mibAttribute;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_NEXT_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MIB_GET_NEXT.confirm -------------------------- */
+typedef struct UnifiMgtMibGetNextCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_DataBlock mibAttribute;
+} UnifiMgtMibGetNextCfm_Evt;
+
+#define send_unifi_mgt_mib_get_next_cfm(context, pid, p1_status, p2_mibAttribute) \
+{ \
+ UnifiMgtMibGetNextCfm_Evt *evt = (UnifiMgtMibGetNextCfm_Evt*) osa_malloc(sizeof(UnifiMgtMibGetNextCfm_Evt));\
+ evt->status = p1_status;\
+ evt->mibAttribute = p2_mibAttribute;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_NEXT_CFM_ID);\
+}
+
+#define send_unifi_mgt_mib_get_next_cfm_external(context, pid, p1_status, p2_mibAttribute) \
+{ \
+ UnifiMgtMibGetNextCfm_Evt *evt = (UnifiMgtMibGetNextCfm_Evt*) osa_malloc(sizeof(UnifiMgtMibGetNextCfm_Evt));\
+ evt->status = p1_status;\
+ evt->mibAttribute = p2_mibAttribute;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIB_GET_NEXT_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_SCAN_FULL.request -------------------------- */
+typedef struct UnifiMgtScanFullReq_Evt
+{
+ FsmEvent common;
+ unifi_SSID ssid;
+ Boolean forceScan;
+ unifi_ScanType scanType;
+ unifi_DataBlock channelList;
+} UnifiMgtScanFullReq_Evt;
+
+#define send_unifi_mgt_scan_full_req(context, pid, p1_ssid, p2_forceScan, p3_scanType, p4_channelList) \
+{ \
+ UnifiMgtScanFullReq_Evt *evt = (UnifiMgtScanFullReq_Evt*) osa_malloc(sizeof(UnifiMgtScanFullReq_Evt));\
+ evt->ssid = p1_ssid;\
+ evt->forceScan = p2_forceScan;\
+ evt->scanType = p3_scanType;\
+ evt->channelList = p4_channelList;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_FULL_REQ_ID);\
+}
+
+#define send_unifi_mgt_scan_full_req_external(context, pid, p1_ssid, p2_forceScan, p3_scanType, p4_channelList) \
+{ \
+ UnifiMgtScanFullReq_Evt *evt = (UnifiMgtScanFullReq_Evt*) osa_malloc(sizeof(UnifiMgtScanFullReq_Evt));\
+ evt->ssid = p1_ssid;\
+ evt->forceScan = p2_forceScan;\
+ evt->scanType = p3_scanType;\
+ evt->channelList = p4_channelList;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_FULL_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_SCAN_FULL.confirm -------------------------- */
+typedef struct UnifiMgtScanFullCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtScanFullCfm_Evt;
+
+#define send_unifi_mgt_scan_full_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtScanFullCfm_Evt *evt = (UnifiMgtScanFullCfm_Evt*) osa_malloc(sizeof(UnifiMgtScanFullCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_FULL_CFM_ID);\
+}
+
+#define send_unifi_mgt_scan_full_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtScanFullCfm_Evt *evt = (UnifiMgtScanFullCfm_Evt*) osa_malloc(sizeof(UnifiMgtScanFullCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_FULL_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_SCAN_RESULTS_GET.request -------------------------- */
+typedef struct UnifiMgtScanResultsGetReq_Evt
+{
+ FsmEvent common;
+} UnifiMgtScanResultsGetReq_Evt;
+
+#define send_unifi_mgt_scan_results_get_req(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_MGT_SCAN_RESULTS_GET_REQ_ID);\
+}
+
+#define send_unifi_mgt_scan_results_get_req_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_MGT_SCAN_RESULTS_GET_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_SCAN_RESULTS_GET.confirm -------------------------- */
+typedef struct UnifiMgtScanResultsGetCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_ScanResultList resultsBuffer;
+} UnifiMgtScanResultsGetCfm_Evt;
+
+#define send_unifi_mgt_scan_results_get_cfm(context, pid, p1_status, p2_resultsBuffer) \
+{ \
+ UnifiMgtScanResultsGetCfm_Evt *evt = (UnifiMgtScanResultsGetCfm_Evt*) osa_malloc(sizeof(UnifiMgtScanResultsGetCfm_Evt));\
+ evt->status = p1_status;\
+ evt->resultsBuffer = p2_resultsBuffer;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_RESULTS_GET_CFM_ID);\
+}
+
+#define send_unifi_mgt_scan_results_get_cfm_external(context, pid, p1_status, p2_resultsBuffer) \
+{ \
+ UnifiMgtScanResultsGetCfm_Evt *evt = (UnifiMgtScanResultsGetCfm_Evt*) osa_malloc(sizeof(UnifiMgtScanResultsGetCfm_Evt));\
+ evt->status = p1_status;\
+ evt->resultsBuffer = p2_resultsBuffer;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_RESULTS_GET_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_SCAN_RESULT.indication -------------------------- */
+typedef struct UnifiMgtScanResultInd_Evt
+{
+ FsmEvent common;
+ unifi_ScanResult result;
+} UnifiMgtScanResultInd_Evt;
+
+#define send_unifi_mgt_scan_result_ind(context, pid, p1_result) \
+{ \
+ UnifiMgtScanResultInd_Evt *evt = (UnifiMgtScanResultInd_Evt*) osa_malloc(sizeof(UnifiMgtScanResultInd_Evt));\
+ evt->result = p1_result;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_RESULT_IND_ID);\
+}
+
+#define send_unifi_mgt_scan_result_ind_external(context, pid, p1_result) \
+{ \
+ UnifiMgtScanResultInd_Evt *evt = (UnifiMgtScanResultInd_Evt*) osa_malloc(sizeof(UnifiMgtScanResultInd_Evt));\
+ evt->result = p1_result;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_SCAN_RESULT_IND_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_CONNECT.request -------------------------- */
+typedef struct UnifiMgtConnectReq_Evt
+{
+ FsmEvent common;
+ unifi_ConnectionConfig connectionConfig;
+} UnifiMgtConnectReq_Evt;
+
+#define send_unifi_mgt_connect_req(context, pid, p1_connectionConfig) \
+{ \
+ UnifiMgtConnectReq_Evt *evt = (UnifiMgtConnectReq_Evt*) osa_malloc(sizeof(UnifiMgtConnectReq_Evt));\
+ evt->connectionConfig = p1_connectionConfig;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_CONNECT_REQ_ID);\
+}
+
+#define send_unifi_mgt_connect_req_external(context, pid, p1_connectionConfig) \
+{ \
+ UnifiMgtConnectReq_Evt *evt = (UnifiMgtConnectReq_Evt*) osa_malloc(sizeof(UnifiMgtConnectReq_Evt));\
+ evt->connectionConfig = p1_connectionConfig;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_CONNECT_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_CONNECT.confirm -------------------------- */
+typedef struct UnifiMgtConnectCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtConnectCfm_Evt;
+
+#define send_unifi_mgt_connect_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtConnectCfm_Evt *evt = (UnifiMgtConnectCfm_Evt*) osa_malloc(sizeof(UnifiMgtConnectCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_CONNECT_CFM_ID);\
+}
+
+#define send_unifi_mgt_connect_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtConnectCfm_Evt *evt = (UnifiMgtConnectCfm_Evt*) osa_malloc(sizeof(UnifiMgtConnectCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_CONNECT_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MEDIA_STATUS.indication -------------------------- */
+typedef struct UnifiMgtMediaStatusInd_Evt
+{
+ FsmEvent common;
+ unifi_MediaStatus mediaStatus;
+ unifi_ConnectionInfo connectionInfo;
+} UnifiMgtMediaStatusInd_Evt;
+
+#define send_unifi_mgt_media_status_ind(context, pid, p1_mediaStatus, p2_connectionInfo) \
+{ \
+ UnifiMgtMediaStatusInd_Evt *evt = (UnifiMgtMediaStatusInd_Evt*) osa_malloc(sizeof(UnifiMgtMediaStatusInd_Evt));\
+ evt->mediaStatus = p1_mediaStatus;\
+ evt->connectionInfo = p2_connectionInfo;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MEDIA_STATUS_IND_ID);\
+}
+
+#define send_unifi_mgt_media_status_ind_external(context, pid, p1_mediaStatus, p2_connectionInfo) \
+{ \
+ UnifiMgtMediaStatusInd_Evt *evt = (UnifiMgtMediaStatusInd_Evt*) osa_malloc(sizeof(UnifiMgtMediaStatusInd_Evt));\
+ evt->mediaStatus = p1_mediaStatus;\
+ evt->connectionInfo = p2_connectionInfo;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MEDIA_STATUS_IND_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_CONNECTION_QUALITY.indication -------------------------- */
+typedef struct UnifiMgtConnectionQualityInd_Evt
+{
+ FsmEvent common;
+ unifi_ConnectionStats connectionStats;
+} UnifiMgtConnectionQualityInd_Evt;
+
+#define send_unifi_mgt_connection_quality_ind(context, pid, p1_connectionStats) \
+{ \
+ UnifiMgtConnectionQualityInd_Evt *evt = (UnifiMgtConnectionQualityInd_Evt*) osa_malloc(sizeof(UnifiMgtConnectionQualityInd_Evt));\
+ evt->connectionStats = p1_connectionStats;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_CONNECTION_QUALITY_IND_ID);\
+}
+
+#define send_unifi_mgt_connection_quality_ind_external(context, pid, p1_connectionStats) \
+{ \
+ UnifiMgtConnectionQualityInd_Evt *evt = (UnifiMgtConnectionQualityInd_Evt*) osa_malloc(sizeof(UnifiMgtConnectionQualityInd_Evt));\
+ evt->connectionStats = p1_connectionStats;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_CONNECTION_QUALITY_IND_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_DISCONNECT.request -------------------------- */
+typedef struct UnifiMgtDisconnectReq_Evt
+{
+ FsmEvent common;
+} UnifiMgtDisconnectReq_Evt;
+
+#define send_unifi_mgt_disconnect_req(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_MGT_DISCONNECT_REQ_ID);\
+}
+
+#define send_unifi_mgt_disconnect_req_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_MGT_DISCONNECT_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_DISCONNECT.confirm -------------------------- */
+typedef struct UnifiMgtDisconnectCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtDisconnectCfm_Evt;
+
+#define send_unifi_mgt_disconnect_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtDisconnectCfm_Evt *evt = (UnifiMgtDisconnectCfm_Evt*) osa_malloc(sizeof(UnifiMgtDisconnectCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_DISCONNECT_CFM_ID);\
+}
+
+#define send_unifi_mgt_disconnect_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtDisconnectCfm_Evt *evt = (UnifiMgtDisconnectCfm_Evt*) osa_malloc(sizeof(UnifiMgtDisconnectCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_DISCONNECT_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MULTICAST_ADDRESS.request -------------------------- */
+typedef struct UnifiMgtMulticastAddressReq_Evt
+{
+ FsmEvent common;
+ unifi_ListAction action;
+ unifi_MulticastAddressList setAddresses;
+} UnifiMgtMulticastAddressReq_Evt;
+
+#define send_unifi_mgt_multicast_address_req(context, pid, p1_action, p2_setAddresses) \
+{ \
+ UnifiMgtMulticastAddressReq_Evt *evt = (UnifiMgtMulticastAddressReq_Evt*) osa_malloc(sizeof(UnifiMgtMulticastAddressReq_Evt));\
+ evt->action = p1_action;\
+ evt->setAddresses = p2_setAddresses;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MULTICAST_ADDRESS_REQ_ID);\
+}
+
+#define send_unifi_mgt_multicast_address_req_external(context, pid, p1_action, p2_setAddresses) \
+{ \
+ UnifiMgtMulticastAddressReq_Evt *evt = (UnifiMgtMulticastAddressReq_Evt*) osa_malloc(sizeof(UnifiMgtMulticastAddressReq_Evt));\
+ evt->action = p1_action;\
+ evt->setAddresses = p2_setAddresses;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MULTICAST_ADDRESS_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MULTICAST_ADDRESS.confirm -------------------------- */
+typedef struct UnifiMgtMulticastAddressCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_ListAction action;
+ unifi_MulticastAddressList getAddresses;
+} UnifiMgtMulticastAddressCfm_Evt;
+
+#define send_unifi_mgt_multicast_address_cfm(context, pid, p1_status, p2_action, p3_getAddresses) \
+{ \
+ UnifiMgtMulticastAddressCfm_Evt *evt = (UnifiMgtMulticastAddressCfm_Evt*) osa_malloc(sizeof(UnifiMgtMulticastAddressCfm_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ evt->getAddresses = p3_getAddresses;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MULTICAST_ADDRESS_CFM_ID);\
+}
+
+#define send_unifi_mgt_multicast_address_cfm_external(context, pid, p1_status, p2_action, p3_getAddresses) \
+{ \
+ UnifiMgtMulticastAddressCfm_Evt *evt = (UnifiMgtMulticastAddressCfm_Evt*) osa_malloc(sizeof(UnifiMgtMulticastAddressCfm_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ evt->getAddresses = p3_getAddresses;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MULTICAST_ADDRESS_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_MIC_FAILURE.indication -------------------------- */
+typedef struct UnifiMgtMicFailureInd_Evt
+{
+ FsmEvent common;
+ Boolean secondFailure;
+ uint16 count;
+ unifi_MACAddress address;
+ unifi_KeyType keyType;
+ uint16 keyId;
+ unifi_SequenceCount tSC;
+} UnifiMgtMicFailureInd_Evt;
+
+#define send_unifi_mgt_mic_failure_ind(context, pid, p1_secondFailure, p2_count, p3_address, p4_keyType, p5_keyId, p6_tSC) \
+{ \
+ UnifiMgtMicFailureInd_Evt *evt = (UnifiMgtMicFailureInd_Evt*) osa_malloc(sizeof(UnifiMgtMicFailureInd_Evt));\
+ evt->secondFailure = p1_secondFailure;\
+ evt->count = p2_count;\
+ evt->address = p3_address;\
+ evt->keyType = p4_keyType;\
+ evt->keyId = p5_keyId;\
+ evt->tSC = p6_tSC;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIC_FAILURE_IND_ID);\
+}
+
+#define send_unifi_mgt_mic_failure_ind_external(context, pid, p1_secondFailure, p2_count, p3_address, p4_keyType, p5_keyId, p6_tSC) \
+{ \
+ UnifiMgtMicFailureInd_Evt *evt = (UnifiMgtMicFailureInd_Evt*) osa_malloc(sizeof(UnifiMgtMicFailureInd_Evt));\
+ evt->secondFailure = p1_secondFailure;\
+ evt->count = p2_count;\
+ evt->address = p3_address;\
+ evt->keyType = p4_keyType;\
+ evt->keyId = p5_keyId;\
+ evt->tSC = p6_tSC;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_MIC_FAILURE_IND_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_PMKID_CANDIDATE_LIST.indication -------------------------- */
+typedef struct UnifiMgtPmkidCandidateListInd_Evt
+{
+ FsmEvent common;
+ unifi_PmkidCandidateList candidates;
+} UnifiMgtPmkidCandidateListInd_Evt;
+
+#define send_unifi_mgt_pmkid_candidate_list_ind(context, pid, p1_candidates) \
+{ \
+ UnifiMgtPmkidCandidateListInd_Evt *evt = (UnifiMgtPmkidCandidateListInd_Evt*) osa_malloc(sizeof(UnifiMgtPmkidCandidateListInd_Evt));\
+ evt->candidates = p1_candidates;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_PMKID_CANDIDATE_LIST_IND_ID);\
+}
+
+#define send_unifi_mgt_pmkid_candidate_list_ind_external(context, pid, p1_candidates) \
+{ \
+ UnifiMgtPmkidCandidateListInd_Evt *evt = (UnifiMgtPmkidCandidateListInd_Evt*) osa_malloc(sizeof(UnifiMgtPmkidCandidateListInd_Evt));\
+ evt->candidates = p1_candidates;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_PMKID_CANDIDATE_LIST_IND_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_PMKID.request -------------------------- */
+typedef struct UnifiMgtPmkidReq_Evt
+{
+ FsmEvent common;
+ unifi_ListAction action;
+ unifi_PmkidList setPmkidList;
+} UnifiMgtPmkidReq_Evt;
+
+#define send_unifi_mgt_pmkid_req(context, pid, p1_action, p2_setPmkidList) \
+{ \
+ UnifiMgtPmkidReq_Evt *evt = (UnifiMgtPmkidReq_Evt*) osa_malloc(sizeof(UnifiMgtPmkidReq_Evt));\
+ evt->action = p1_action;\
+ evt->setPmkidList = p2_setPmkidList;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_PMKID_REQ_ID);\
+}
+
+#define send_unifi_mgt_pmkid_req_external(context, pid, p1_action, p2_setPmkidList) \
+{ \
+ UnifiMgtPmkidReq_Evt *evt = (UnifiMgtPmkidReq_Evt*) osa_malloc(sizeof(UnifiMgtPmkidReq_Evt));\
+ evt->action = p1_action;\
+ evt->setPmkidList = p2_setPmkidList;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_PMKID_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_PMKID.confirm -------------------------- */
+typedef struct UnifiMgtPmkidCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_ListAction action;
+ unifi_PmkidList getPmkidList;
+} UnifiMgtPmkidCfm_Evt;
+
+#define send_unifi_mgt_pmkid_cfm(context, pid, p1_status, p2_action, p3_getPmkidList) \
+{ \
+ UnifiMgtPmkidCfm_Evt *evt = (UnifiMgtPmkidCfm_Evt*) osa_malloc(sizeof(UnifiMgtPmkidCfm_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ evt->getPmkidList = p3_getPmkidList;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_PMKID_CFM_ID);\
+}
+
+#define send_unifi_mgt_pmkid_cfm_external(context, pid, p1_status, p2_action, p3_getPmkidList) \
+{ \
+ UnifiMgtPmkidCfm_Evt *evt = (UnifiMgtPmkidCfm_Evt*) osa_malloc(sizeof(UnifiMgtPmkidCfm_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ evt->getPmkidList = p3_getPmkidList;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_PMKID_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_KEY.request -------------------------- */
+typedef struct UnifiMgtKeyReq_Evt
+{
+ FsmEvent common;
+ unifi_ListAction action;
+ unifi_Key key;
+} UnifiMgtKeyReq_Evt;
+
+#define send_unifi_mgt_key_req(context, pid, p1_action, p2_key) \
+{ \
+ UnifiMgtKeyReq_Evt *evt = (UnifiMgtKeyReq_Evt*) osa_malloc(sizeof(UnifiMgtKeyReq_Evt));\
+ evt->action = p1_action;\
+ evt->key = p2_key;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_KEY_REQ_ID);\
+}
+
+#define send_unifi_mgt_key_req_external(context, pid, p1_action, p2_key) \
+{ \
+ UnifiMgtKeyReq_Evt *evt = (UnifiMgtKeyReq_Evt*) osa_malloc(sizeof(UnifiMgtKeyReq_Evt));\
+ evt->action = p1_action;\
+ evt->key = p2_key;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_KEY_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_KEY.confirm -------------------------- */
+typedef struct UnifiMgtKeyCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_ListAction action;
+} UnifiMgtKeyCfm_Evt;
+
+#define send_unifi_mgt_key_cfm(context, pid, p1_status, p2_action) \
+{ \
+ UnifiMgtKeyCfm_Evt *evt = (UnifiMgtKeyCfm_Evt*) osa_malloc(sizeof(UnifiMgtKeyCfm_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_KEY_CFM_ID);\
+}
+
+#define send_unifi_mgt_key_cfm_external(context, pid, p1_status, p2_action) \
+{ \
+ UnifiMgtKeyCfm_Evt *evt = (UnifiMgtKeyCfm_Evt*) osa_malloc(sizeof(UnifiMgtKeyCfm_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_KEY_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_PACKET_FILTER_SET.request -------------------------- */
+typedef struct UnifiMgtPacketFilterSetReq_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock filter;
+ unifi_PacketFilterMode mode;
+ unifi_IPV4Address arpFilterAddress;
+} UnifiMgtPacketFilterSetReq_Evt;
+
+#define send_unifi_mgt_packet_filter_set_req(context, pid, p1_filter, p2_mode, p3_arpFilterAddress) \
+{ \
+ UnifiMgtPacketFilterSetReq_Evt *evt = (UnifiMgtPacketFilterSetReq_Evt*) osa_malloc(sizeof(UnifiMgtPacketFilterSetReq_Evt));\
+ evt->filter = p1_filter;\
+ evt->mode = p2_mode;\
+ evt->arpFilterAddress = p3_arpFilterAddress;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_PACKET_FILTER_SET_REQ_ID);\
+}
+
+#define send_unifi_mgt_packet_filter_set_req_external(context, pid, p1_filter, p2_mode, p3_arpFilterAddress) \
+{ \
+ UnifiMgtPacketFilterSetReq_Evt *evt = (UnifiMgtPacketFilterSetReq_Evt*) osa_malloc(sizeof(UnifiMgtPacketFilterSetReq_Evt));\
+ evt->filter = p1_filter;\
+ evt->mode = p2_mode;\
+ evt->arpFilterAddress = p3_arpFilterAddress;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_PACKET_FILTER_SET_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_PACKET_FILTER_SET.confirm -------------------------- */
+typedef struct UnifiMgtPacketFilterSetCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiMgtPacketFilterSetCfm_Evt;
+
+#define send_unifi_mgt_packet_filter_set_cfm(context, pid, p1_status) \
+{ \
+ UnifiMgtPacketFilterSetCfm_Evt *evt = (UnifiMgtPacketFilterSetCfm_Evt*) osa_malloc(sizeof(UnifiMgtPacketFilterSetCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_PACKET_FILTER_SET_CFM_ID);\
+}
+
+#define send_unifi_mgt_packet_filter_set_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiMgtPacketFilterSetCfm_Evt *evt = (UnifiMgtPacketFilterSetCfm_Evt*) osa_malloc(sizeof(UnifiMgtPacketFilterSetCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_PACKET_FILTER_SET_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_TSPEC.request -------------------------- */
+typedef struct UnifiMgtTspecReq_Evt
+{
+ FsmEvent common;
+ unifi_ListAction action;
+ uint32 transactionId;
+ Boolean strict;
+ unifi_DataBlock tspec;
+ unifi_DataBlock tclas;
+} UnifiMgtTspecReq_Evt;
+
+#define send_unifi_mgt_tspec_req(context, pid, p1_action, p2_transactionId, p3_strict, p4_tspec, p5_tclas) \
+{ \
+ UnifiMgtTspecReq_Evt *evt = (UnifiMgtTspecReq_Evt*) osa_malloc(sizeof(UnifiMgtTspecReq_Evt));\
+ evt->action = p1_action;\
+ evt->transactionId = p2_transactionId;\
+ evt->strict = p3_strict;\
+ evt->tspec = p4_tspec;\
+ evt->tclas = p5_tclas;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_TSPEC_REQ_ID);\
+}
+
+#define send_unifi_mgt_tspec_req_external(context, pid, p1_action, p2_transactionId, p3_strict, p4_tspec, p5_tclas) \
+{ \
+ UnifiMgtTspecReq_Evt *evt = (UnifiMgtTspecReq_Evt*) osa_malloc(sizeof(UnifiMgtTspecReq_Evt));\
+ evt->action = p1_action;\
+ evt->transactionId = p2_transactionId;\
+ evt->strict = p3_strict;\
+ evt->tspec = p4_tspec;\
+ evt->tclas = p5_tclas;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_TSPEC_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_TSPEC.confirm -------------------------- */
+typedef struct UnifiMgtTspecCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ uint32 transactionId;
+ unifi_TspecResultCode tspecResultCode;
+ unifi_DataBlock tspec;
+} UnifiMgtTspecCfm_Evt;
+
+#define send_unifi_mgt_tspec_cfm(context, pid, p1_status, p2_transactionId, p3_tspecResultCode, p4_tspec) \
+{ \
+ UnifiMgtTspecCfm_Evt *evt = (UnifiMgtTspecCfm_Evt*) osa_malloc(sizeof(UnifiMgtTspecCfm_Evt));\
+ evt->status = p1_status;\
+ evt->transactionId = p2_transactionId;\
+ evt->tspecResultCode = p3_tspecResultCode;\
+ evt->tspec = p4_tspec;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_TSPEC_CFM_ID);\
+}
+
+#define send_unifi_mgt_tspec_cfm_external(context, pid, p1_status, p2_transactionId, p3_tspecResultCode, p4_tspec) \
+{ \
+ UnifiMgtTspecCfm_Evt *evt = (UnifiMgtTspecCfm_Evt*) osa_malloc(sizeof(UnifiMgtTspecCfm_Evt));\
+ evt->status = p1_status;\
+ evt->transactionId = p2_transactionId;\
+ evt->tspecResultCode = p3_tspecResultCode;\
+ evt->tspec = p4_tspec;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_TSPEC_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_MGT_TSPEC.indication -------------------------- */
+typedef struct UnifiMgtTspecInd_Evt
+{
+ FsmEvent common;
+ unifi_ListAction action;
+ uint32 transactionId;
+} UnifiMgtTspecInd_Evt;
+
+#define send_unifi_mgt_tspec_ind(context, pid, p1_action, p2_transactionId) \
+{ \
+ UnifiMgtTspecInd_Evt *evt = (UnifiMgtTspecInd_Evt*) osa_malloc(sizeof(UnifiMgtTspecInd_Evt));\
+ evt->action = p1_action;\
+ evt->transactionId = p2_transactionId;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_MGT_TSPEC_IND_ID);\
+}
+
+#define send_unifi_mgt_tspec_ind_external(context, pid, p1_action, p2_transactionId) \
+{ \
+ UnifiMgtTspecInd_Evt *evt = (UnifiMgtTspecInd_Evt*) osa_malloc(sizeof(UnifiMgtTspecInd_Evt));\
+ evt->action = p1_action;\
+ evt->transactionId = p2_transactionId;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_MGT_TSPEC_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_ON.request -------------------------- */
+typedef struct UnifiSysWifiOnReq_Evt
+{
+ FsmEvent common;
+} UnifiSysWifiOnReq_Evt;
+
+#define send_unifi_sys_wifi_on_req(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_SYS_WIFI_ON_REQ_ID);\
+}
+
+#define send_unifi_sys_wifi_on_req_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_SYS_WIFI_ON_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_ON.indication -------------------------- */
+typedef struct UnifiSysWifiOnInd_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_Versions versions;
+} UnifiSysWifiOnInd_Evt;
+
+#define send_unifi_sys_wifi_on_ind(context, pid, p1_status, p2_versions) \
+{ \
+ UnifiSysWifiOnInd_Evt *evt = (UnifiSysWifiOnInd_Evt*) osa_malloc(sizeof(UnifiSysWifiOnInd_Evt));\
+ evt->status = p1_status;\
+ evt->versions = p2_versions;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_ON_IND_ID);\
+}
+
+#define send_unifi_sys_wifi_on_ind_external(context, pid, p1_status, p2_versions) \
+{ \
+ UnifiSysWifiOnInd_Evt *evt = (UnifiSysWifiOnInd_Evt*) osa_malloc(sizeof(UnifiSysWifiOnInd_Evt));\
+ evt->status = p1_status;\
+ evt->versions = p2_versions;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_ON_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_ON.response -------------------------- */
+typedef struct UnifiSysWifiOnRsp_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_MACAddress stationMacAddress;
+} UnifiSysWifiOnRsp_Evt;
+
+#define send_unifi_sys_wifi_on_rsp(context, pid, p1_status, p2_stationMacAddress) \
+{ \
+ UnifiSysWifiOnRsp_Evt *evt = (UnifiSysWifiOnRsp_Evt*) osa_malloc(sizeof(UnifiSysWifiOnRsp_Evt));\
+ evt->status = p1_status;\
+ evt->stationMacAddress = p2_stationMacAddress;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_ON_RSP_ID);\
+}
+
+#define send_unifi_sys_wifi_on_rsp_external(context, pid, p1_status, p2_stationMacAddress) \
+{ \
+ UnifiSysWifiOnRsp_Evt *evt = (UnifiSysWifiOnRsp_Evt*) osa_malloc(sizeof(UnifiSysWifiOnRsp_Evt));\
+ evt->status = p1_status;\
+ evt->stationMacAddress = p2_stationMacAddress;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_ON_RSP_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_ON.confirm -------------------------- */
+typedef struct UnifiSysWifiOnCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiSysWifiOnCfm_Evt;
+
+#define send_unifi_sys_wifi_on_cfm(context, pid, p1_status) \
+{ \
+ UnifiSysWifiOnCfm_Evt *evt = (UnifiSysWifiOnCfm_Evt*) osa_malloc(sizeof(UnifiSysWifiOnCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_ON_CFM_ID);\
+}
+
+#define send_unifi_sys_wifi_on_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiSysWifiOnCfm_Evt *evt = (UnifiSysWifiOnCfm_Evt*) osa_malloc(sizeof(UnifiSysWifiOnCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_ON_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_OFF.request -------------------------- */
+typedef struct UnifiSysWifiOffReq_Evt
+{
+ FsmEvent common;
+} UnifiSysWifiOffReq_Evt;
+
+#define send_unifi_sys_wifi_off_req(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_SYS_WIFI_OFF_REQ_ID);\
+}
+
+#define send_unifi_sys_wifi_off_req_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_SYS_WIFI_OFF_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_OFF.indication -------------------------- */
+typedef struct UnifiSysWifiOffInd_Evt
+{
+ FsmEvent common;
+ unifi_ControlIndication controlIndication;
+} UnifiSysWifiOffInd_Evt;
+
+#define send_unifi_sys_wifi_off_ind(context, pid, p1_controlIndication) \
+{ \
+ UnifiSysWifiOffInd_Evt *evt = (UnifiSysWifiOffInd_Evt*) osa_malloc(sizeof(UnifiSysWifiOffInd_Evt));\
+ evt->controlIndication = p1_controlIndication;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_OFF_IND_ID);\
+}
+
+#define send_unifi_sys_wifi_off_ind_external(context, pid, p1_controlIndication) \
+{ \
+ UnifiSysWifiOffInd_Evt *evt = (UnifiSysWifiOffInd_Evt*) osa_malloc(sizeof(UnifiSysWifiOffInd_Evt));\
+ evt->controlIndication = p1_controlIndication;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_WIFI_OFF_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_OFF.response -------------------------- */
+typedef struct UnifiSysWifiOffRsp_Evt
+{
+ FsmEvent common;
+} UnifiSysWifiOffRsp_Evt;
+
+#define send_unifi_sys_wifi_off_rsp(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_SYS_WIFI_OFF_RSP_ID);\
+}
+
+#define send_unifi_sys_wifi_off_rsp_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_SYS_WIFI_OFF_RSP_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_WIFI_OFF.confirm -------------------------- */
+typedef struct UnifiSysWifiOffCfm_Evt
+{
+ FsmEvent common;
+} UnifiSysWifiOffCfm_Evt;
+
+#define send_unifi_sys_wifi_off_cfm(context, pid) \
+{ \
+ fsm_send_event(context, NULL, pid, UNIFI_SYS_WIFI_OFF_CFM_ID);\
+}
+
+#define send_unifi_sys_wifi_off_cfm_external(context, pid) \
+{ \
+ fsm_send_event_external(context, NULL, pid, UNIFI_SYS_WIFI_OFF_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_SUSPEND.indication -------------------------- */
+typedef struct UnifiSysSuspendInd_Evt
+{
+ FsmEvent common;
+ Boolean hardSuspend;
+ Boolean d3Suspend;
+} UnifiSysSuspendInd_Evt;
+
+#define send_unifi_sys_suspend_ind(context, pid, p1_hardSuspend, p2_d3Suspend) \
+{ \
+ UnifiSysSuspendInd_Evt *evt = (UnifiSysSuspendInd_Evt*) osa_malloc(sizeof(UnifiSysSuspendInd_Evt));\
+ evt->hardSuspend = p1_hardSuspend;\
+ evt->d3Suspend = p2_d3Suspend;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_SUSPEND_IND_ID);\
+}
+
+#define send_unifi_sys_suspend_ind_external(context, pid, p1_hardSuspend, p2_d3Suspend) \
+{ \
+ UnifiSysSuspendInd_Evt *evt = (UnifiSysSuspendInd_Evt*) osa_malloc(sizeof(UnifiSysSuspendInd_Evt));\
+ evt->hardSuspend = p1_hardSuspend;\
+ evt->d3Suspend = p2_d3Suspend;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_SUSPEND_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_SUSPEND.response -------------------------- */
+typedef struct UnifiSysSuspendRsp_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiSysSuspendRsp_Evt;
+
+#define send_unifi_sys_suspend_rsp(context, pid, p1_status) \
+{ \
+ UnifiSysSuspendRsp_Evt *evt = (UnifiSysSuspendRsp_Evt*) osa_malloc(sizeof(UnifiSysSuspendRsp_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_SUSPEND_RSP_ID);\
+}
+
+#define send_unifi_sys_suspend_rsp_external(context, pid, p1_status) \
+{ \
+ UnifiSysSuspendRsp_Evt *evt = (UnifiSysSuspendRsp_Evt*) osa_malloc(sizeof(UnifiSysSuspendRsp_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_SUSPEND_RSP_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_RESUME.indication -------------------------- */
+typedef struct UnifiSysResumeInd_Evt
+{
+ FsmEvent common;
+ Boolean resumePowerMaintained;
+} UnifiSysResumeInd_Evt;
+
+#define send_unifi_sys_resume_ind(context, pid, p1_resumePowerMaintained) \
+{ \
+ UnifiSysResumeInd_Evt *evt = (UnifiSysResumeInd_Evt*) osa_malloc(sizeof(UnifiSysResumeInd_Evt));\
+ evt->resumePowerMaintained = p1_resumePowerMaintained;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_RESUME_IND_ID);\
+}
+
+#define send_unifi_sys_resume_ind_external(context, pid, p1_resumePowerMaintained) \
+{ \
+ UnifiSysResumeInd_Evt *evt = (UnifiSysResumeInd_Evt*) osa_malloc(sizeof(UnifiSysResumeInd_Evt));\
+ evt->resumePowerMaintained = p1_resumePowerMaintained;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_RESUME_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_RESUME.response -------------------------- */
+typedef struct UnifiSysResumeRsp_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiSysResumeRsp_Evt;
+
+#define send_unifi_sys_resume_rsp(context, pid, p1_status) \
+{ \
+ UnifiSysResumeRsp_Evt *evt = (UnifiSysResumeRsp_Evt*) osa_malloc(sizeof(UnifiSysResumeRsp_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_RESUME_RSP_ID);\
+}
+
+#define send_unifi_sys_resume_rsp_external(context, pid, p1_status) \
+{ \
+ UnifiSysResumeRsp_Evt *evt = (UnifiSysResumeRsp_Evt*) osa_malloc(sizeof(UnifiSysResumeRsp_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_RESUME_RSP_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_HIP.request -------------------------- */
+typedef struct UnifiSysHipReq_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock mlmeCommand;
+ unifi_DataBlock dataRef1;
+ unifi_DataBlock dataRef2;
+} UnifiSysHipReq_Evt;
+
+#define send_unifi_sys_hip_req(context, pid, p1_mlmeCommand, p2_dataRef1, p3_dataRef2) \
+{ \
+ UnifiSysHipReq_Evt *evt = (UnifiSysHipReq_Evt*) osa_malloc(sizeof(UnifiSysHipReq_Evt));\
+ evt->mlmeCommand = p1_mlmeCommand;\
+ evt->dataRef1 = p2_dataRef1;\
+ evt->dataRef2 = p3_dataRef2;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_HIP_REQ_ID);\
+}
+
+#define send_unifi_sys_hip_req_external(context, pid, p1_mlmeCommand, p2_dataRef1, p3_dataRef2) \
+{ \
+ UnifiSysHipReq_Evt *evt = (UnifiSysHipReq_Evt*) osa_malloc(sizeof(UnifiSysHipReq_Evt));\
+ evt->mlmeCommand = p1_mlmeCommand;\
+ evt->dataRef1 = p2_dataRef1;\
+ evt->dataRef2 = p3_dataRef2;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_HIP_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_HIP.indication -------------------------- */
+typedef struct UnifiSysHipInd_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock mlmeCommand;
+ unifi_DataBlock dataRef1;
+ unifi_DataBlock dataRef2;
+} UnifiSysHipInd_Evt;
+
+#define send_unifi_sys_hip_ind(context, pid, p1_mlmeCommand, p2_dataRef1, p3_dataRef2) \
+{ \
+ UnifiSysHipInd_Evt *evt = (UnifiSysHipInd_Evt*) osa_malloc(sizeof(UnifiSysHipInd_Evt));\
+ evt->mlmeCommand = p1_mlmeCommand;\
+ evt->dataRef1 = p2_dataRef1;\
+ evt->dataRef2 = p3_dataRef2;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_HIP_IND_ID);\
+}
+
+#define send_unifi_sys_hip_ind_external(context, pid, p1_mlmeCommand, p2_dataRef1, p3_dataRef2) \
+{ \
+ UnifiSysHipInd_Evt *evt = (UnifiSysHipInd_Evt*) osa_malloc(sizeof(UnifiSysHipInd_Evt));\
+ evt->mlmeCommand = p1_mlmeCommand;\
+ evt->dataRef1 = p2_dataRef1;\
+ evt->dataRef2 = p3_dataRef2;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_HIP_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_QOS_CONTROL.request -------------------------- */
+typedef struct UnifiSysQosControlReq_Evt
+{
+ FsmEvent common;
+ unifi_QoSControl control;
+} UnifiSysQosControlReq_Evt;
+
+#define send_unifi_sys_qos_control_req(context, pid, p1_control) \
+{ \
+ UnifiSysQosControlReq_Evt *evt = (UnifiSysQosControlReq_Evt*) osa_malloc(sizeof(UnifiSysQosControlReq_Evt));\
+ evt->control = p1_control;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_QOS_CONTROL_REQ_ID);\
+}
+
+#define send_unifi_sys_qos_control_req_external(context, pid, p1_control) \
+{ \
+ UnifiSysQosControlReq_Evt *evt = (UnifiSysQosControlReq_Evt*) osa_malloc(sizeof(UnifiSysQosControlReq_Evt));\
+ evt->control = p1_control;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_QOS_CONTROL_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_QOS_CONTROL.confirm -------------------------- */
+typedef struct UnifiSysQosControlCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiSysQosControlCfm_Evt;
+
+#define send_unifi_sys_qos_control_cfm(context, pid, p1_status) \
+{ \
+ UnifiSysQosControlCfm_Evt *evt = (UnifiSysQosControlCfm_Evt*) osa_malloc(sizeof(UnifiSysQosControlCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_QOS_CONTROL_CFM_ID);\
+}
+
+#define send_unifi_sys_qos_control_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiSysQosControlCfm_Evt *evt = (UnifiSysQosControlCfm_Evt*) osa_malloc(sizeof(UnifiSysQosControlCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_QOS_CONTROL_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_PORT_CONFIGURE.request -------------------------- */
+typedef struct UnifiSysPortConfigureReq_Evt
+{
+ FsmEvent common;
+ unifi_PortAction uncontrolledPortAction;
+ unifi_PortAction controlledPortAction;
+ unifi_MACAddress macAddress;
+} UnifiSysPortConfigureReq_Evt;
+
+#define send_unifi_sys_port_configure_req(context, pid, p1_uncontrolledPortAction, p2_controlledPortAction, p3_macAddress) \
+{ \
+ UnifiSysPortConfigureReq_Evt *evt = (UnifiSysPortConfigureReq_Evt*) osa_malloc(sizeof(UnifiSysPortConfigureReq_Evt));\
+ evt->uncontrolledPortAction = p1_uncontrolledPortAction;\
+ evt->controlledPortAction = p2_controlledPortAction;\
+ evt->macAddress = p3_macAddress;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_PORT_CONFIGURE_REQ_ID);\
+}
+
+#define send_unifi_sys_port_configure_req_external(context, pid, p1_uncontrolledPortAction, p2_controlledPortAction, p3_macAddress) \
+{ \
+ UnifiSysPortConfigureReq_Evt *evt = (UnifiSysPortConfigureReq_Evt*) osa_malloc(sizeof(UnifiSysPortConfigureReq_Evt));\
+ evt->uncontrolledPortAction = p1_uncontrolledPortAction;\
+ evt->controlledPortAction = p2_controlledPortAction;\
+ evt->macAddress = p3_macAddress;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_PORT_CONFIGURE_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_PORT_CONFIGURE.confirm -------------------------- */
+typedef struct UnifiSysPortConfigureCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_MACAddress macAddress;
+} UnifiSysPortConfigureCfm_Evt;
+
+#define send_unifi_sys_port_configure_cfm(context, pid, p1_status, p2_macAddress) \
+{ \
+ UnifiSysPortConfigureCfm_Evt *evt = (UnifiSysPortConfigureCfm_Evt*) osa_malloc(sizeof(UnifiSysPortConfigureCfm_Evt));\
+ evt->status = p1_status;\
+ evt->macAddress = p2_macAddress;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_PORT_CONFIGURE_CFM_ID);\
+}
+
+#define send_unifi_sys_port_configure_cfm_external(context, pid, p1_status, p2_macAddress) \
+{ \
+ UnifiSysPortConfigureCfm_Evt *evt = (UnifiSysPortConfigureCfm_Evt*) osa_malloc(sizeof(UnifiSysPortConfigureCfm_Evt));\
+ evt->status = p1_status;\
+ evt->macAddress = p2_macAddress;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_PORT_CONFIGURE_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_CONFIGURE_POWER_MODE.request -------------------------- */
+typedef struct UnifiSysConfigurePowerModeReq_Evt
+{
+ FsmEvent common;
+ unifi_LowPowerMode mode;
+ Boolean wakeHost;
+} UnifiSysConfigurePowerModeReq_Evt;
+
+#define send_unifi_sys_configure_power_mode_req(context, pid, p1_mode, p2_wakeHost) \
+{ \
+ UnifiSysConfigurePowerModeReq_Evt *evt = (UnifiSysConfigurePowerModeReq_Evt*) osa_malloc(sizeof(UnifiSysConfigurePowerModeReq_Evt));\
+ evt->mode = p1_mode;\
+ evt->wakeHost = p2_wakeHost;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_CONFIGURE_POWER_MODE_REQ_ID);\
+}
+
+#define send_unifi_sys_configure_power_mode_req_external(context, pid, p1_mode, p2_wakeHost) \
+{ \
+ UnifiSysConfigurePowerModeReq_Evt *evt = (UnifiSysConfigurePowerModeReq_Evt*) osa_malloc(sizeof(UnifiSysConfigurePowerModeReq_Evt));\
+ evt->mode = p1_mode;\
+ evt->wakeHost = p2_wakeHost;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_CONFIGURE_POWER_MODE_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TRAFFIC_CONFIG.request -------------------------- */
+typedef struct UnifiSysTrafficConfigReq_Evt
+{
+ FsmEvent common;
+ unifi_traffic_configtype type;
+ unifi_traffic_config config;
+} UnifiSysTrafficConfigReq_Evt;
+
+#define send_unifi_sys_traffic_config_req(context, pid, p1_type, p2_config) \
+{ \
+ UnifiSysTrafficConfigReq_Evt *evt = (UnifiSysTrafficConfigReq_Evt*) osa_malloc(sizeof(UnifiSysTrafficConfigReq_Evt));\
+ evt->type = p1_type;\
+ evt->config = p2_config;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_CONFIG_REQ_ID);\
+}
+
+#define send_unifi_sys_traffic_config_req_external(context, pid, p1_type, p2_config) \
+{ \
+ UnifiSysTrafficConfigReq_Evt *evt = (UnifiSysTrafficConfigReq_Evt*) osa_malloc(sizeof(UnifiSysTrafficConfigReq_Evt));\
+ evt->type = p1_type;\
+ evt->config = p2_config;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_CONFIG_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TRAFFIC_SAMPLE.indication -------------------------- */
+typedef struct UnifiSysTrafficSampleInd_Evt
+{
+ FsmEvent common;
+ unifi_traffic_stats stats;
+} UnifiSysTrafficSampleInd_Evt;
+
+#define send_unifi_sys_traffic_sample_ind(context, pid, p1_stats) \
+{ \
+ UnifiSysTrafficSampleInd_Evt *evt = (UnifiSysTrafficSampleInd_Evt*) osa_malloc(sizeof(UnifiSysTrafficSampleInd_Evt));\
+ evt->stats = p1_stats;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_SAMPLE_IND_ID);\
+}
+
+#define send_unifi_sys_traffic_sample_ind_external(context, pid, p1_stats) \
+{ \
+ UnifiSysTrafficSampleInd_Evt *evt = (UnifiSysTrafficSampleInd_Evt*) osa_malloc(sizeof(UnifiSysTrafficSampleInd_Evt));\
+ evt->stats = p1_stats;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_SAMPLE_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TRAFFIC_PROTOCOL.indication -------------------------- */
+typedef struct UnifiSysTrafficProtocolInd_Evt
+{
+ FsmEvent common;
+ unifi_traffic_packettype packetType;
+ unifi_protocol_direction direction;
+ unifi_MACAddress srcAddress;
+} UnifiSysTrafficProtocolInd_Evt;
+
+#define send_unifi_sys_traffic_protocol_ind(context, pid, p1_packetType, p2_direction, p3_srcAddress) \
+{ \
+ UnifiSysTrafficProtocolInd_Evt *evt = (UnifiSysTrafficProtocolInd_Evt*) osa_malloc(sizeof(UnifiSysTrafficProtocolInd_Evt));\
+ evt->packetType = p1_packetType;\
+ evt->direction = p2_direction;\
+ evt->srcAddress = p3_srcAddress;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_PROTOCOL_IND_ID);\
+}
+
+#define send_unifi_sys_traffic_protocol_ind_external(context, pid, p1_packetType, p2_direction, p3_srcAddress) \
+{ \
+ UnifiSysTrafficProtocolInd_Evt *evt = (UnifiSysTrafficProtocolInd_Evt*) osa_malloc(sizeof(UnifiSysTrafficProtocolInd_Evt));\
+ evt->packetType = p1_packetType;\
+ evt->direction = p2_direction;\
+ evt->srcAddress = p3_srcAddress;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_PROTOCOL_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_IP_CONFIGURED.indication -------------------------- */
+typedef struct UnifiSysIpConfiguredInd_Evt
+{
+ FsmEvent common;
+ Boolean ipConfigured;
+} UnifiSysIpConfiguredInd_Evt;
+
+#define send_unifi_sys_ip_configured_ind(context, pid, p1_ipConfigured) \
+{ \
+ UnifiSysIpConfiguredInd_Evt *evt = (UnifiSysIpConfiguredInd_Evt*) osa_malloc(sizeof(UnifiSysIpConfiguredInd_Evt));\
+ evt->ipConfigured = p1_ipConfigured;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_IP_CONFIGURED_IND_ID);\
+}
+
+#define send_unifi_sys_ip_configured_ind_external(context, pid, p1_ipConfigured) \
+{ \
+ UnifiSysIpConfiguredInd_Evt *evt = (UnifiSysIpConfiguredInd_Evt*) osa_malloc(sizeof(UnifiSysIpConfiguredInd_Evt));\
+ evt->ipConfigured = p1_ipConfigured;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_IP_CONFIGURED_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_MEDIA_STATUS.request -------------------------- */
+typedef struct UnifiSysMediaStatusReq_Evt
+{
+ FsmEvent common;
+ unifi_MediaStatus mediaStatus;
+} UnifiSysMediaStatusReq_Evt;
+
+#define send_unifi_sys_media_status_req(context, pid, p1_mediaStatus) \
+{ \
+ UnifiSysMediaStatusReq_Evt *evt = (UnifiSysMediaStatusReq_Evt*) osa_malloc(sizeof(UnifiSysMediaStatusReq_Evt));\
+ evt->mediaStatus = p1_mediaStatus;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_MEDIA_STATUS_REQ_ID);\
+}
+
+#define send_unifi_sys_media_status_req_external(context, pid, p1_mediaStatus) \
+{ \
+ UnifiSysMediaStatusReq_Evt *evt = (UnifiSysMediaStatusReq_Evt*) osa_malloc(sizeof(UnifiSysMediaStatusReq_Evt));\
+ evt->mediaStatus = p1_mediaStatus;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_MEDIA_STATUS_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_MULTICAST_ADDRESS.indication -------------------------- */
+typedef struct UnifiSysMulticastAddressInd_Evt
+{
+ FsmEvent common;
+ unifi_ListAction action;
+ unifi_MulticastAddressList setAddresses;
+} UnifiSysMulticastAddressInd_Evt;
+
+#define send_unifi_sys_multicast_address_ind(context, pid, p1_action, p2_setAddresses) \
+{ \
+ UnifiSysMulticastAddressInd_Evt *evt = (UnifiSysMulticastAddressInd_Evt*) osa_malloc(sizeof(UnifiSysMulticastAddressInd_Evt));\
+ evt->action = p1_action;\
+ evt->setAddresses = p2_setAddresses;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_MULTICAST_ADDRESS_IND_ID);\
+}
+
+#define send_unifi_sys_multicast_address_ind_external(context, pid, p1_action, p2_setAddresses) \
+{ \
+ UnifiSysMulticastAddressInd_Evt *evt = (UnifiSysMulticastAddressInd_Evt*) osa_malloc(sizeof(UnifiSysMulticastAddressInd_Evt));\
+ evt->action = p1_action;\
+ evt->setAddresses = p2_setAddresses;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_MULTICAST_ADDRESS_IND_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_MULTICAST_ADDRESS.response -------------------------- */
+typedef struct UnifiSysMulticastAddressRsp_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+ unifi_ListAction action;
+ unifi_MulticastAddressList getAddresses;
+} UnifiSysMulticastAddressRsp_Evt;
+
+#define send_unifi_sys_multicast_address_rsp(context, pid, p1_status, p2_action, p3_getAddresses) \
+{ \
+ UnifiSysMulticastAddressRsp_Evt *evt = (UnifiSysMulticastAddressRsp_Evt*) osa_malloc(sizeof(UnifiSysMulticastAddressRsp_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ evt->getAddresses = p3_getAddresses;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_MULTICAST_ADDRESS_RSP_ID);\
+}
+
+#define send_unifi_sys_multicast_address_rsp_external(context, pid, p1_status, p2_action, p3_getAddresses) \
+{ \
+ UnifiSysMulticastAddressRsp_Evt *evt = (UnifiSysMulticastAddressRsp_Evt*) osa_malloc(sizeof(UnifiSysMulticastAddressRsp_Evt));\
+ evt->status = p1_status;\
+ evt->action = p2_action;\
+ evt->getAddresses = p3_getAddresses;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_MULTICAST_ADDRESS_RSP_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TCLAS_ADD.request -------------------------- */
+typedef struct UnifiSysTclasAddReq_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock tclas;
+} UnifiSysTclasAddReq_Evt;
+
+#define send_unifi_sys_tclas_add_req(context, pid, p1_tclas) \
+{ \
+ UnifiSysTclasAddReq_Evt *evt = (UnifiSysTclasAddReq_Evt*) osa_malloc(sizeof(UnifiSysTclasAddReq_Evt));\
+ evt->tclas = p1_tclas;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_ADD_REQ_ID);\
+}
+
+#define send_unifi_sys_tclas_add_req_external(context, pid, p1_tclas) \
+{ \
+ UnifiSysTclasAddReq_Evt *evt = (UnifiSysTclasAddReq_Evt*) osa_malloc(sizeof(UnifiSysTclasAddReq_Evt));\
+ evt->tclas = p1_tclas;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_ADD_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TCLAS_ADD.confirm -------------------------- */
+typedef struct UnifiSysTclasAddCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiSysTclasAddCfm_Evt;
+
+#define send_unifi_sys_tclas_add_cfm(context, pid, p1_status) \
+{ \
+ UnifiSysTclasAddCfm_Evt *evt = (UnifiSysTclasAddCfm_Evt*) osa_malloc(sizeof(UnifiSysTclasAddCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_ADD_CFM_ID);\
+}
+
+#define send_unifi_sys_tclas_add_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiSysTclasAddCfm_Evt *evt = (UnifiSysTclasAddCfm_Evt*) osa_malloc(sizeof(UnifiSysTclasAddCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_ADD_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TCLAS_DEL.request -------------------------- */
+typedef struct UnifiSysTclasDelReq_Evt
+{
+ FsmEvent common;
+ unifi_DataBlock tclas;
+} UnifiSysTclasDelReq_Evt;
+
+#define send_unifi_sys_tclas_del_req(context, pid, p1_tclas) \
+{ \
+ UnifiSysTclasDelReq_Evt *evt = (UnifiSysTclasDelReq_Evt*) osa_malloc(sizeof(UnifiSysTclasDelReq_Evt));\
+ evt->tclas = p1_tclas;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_DEL_REQ_ID);\
+}
+
+#define send_unifi_sys_tclas_del_req_external(context, pid, p1_tclas) \
+{ \
+ UnifiSysTclasDelReq_Evt *evt = (UnifiSysTclasDelReq_Evt*) osa_malloc(sizeof(UnifiSysTclasDelReq_Evt));\
+ evt->tclas = p1_tclas;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_DEL_REQ_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TCLAS_DEL.confirm -------------------------- */
+typedef struct UnifiSysTclasDelCfm_Evt
+{
+ FsmEvent common;
+ unifi_Status status;
+} UnifiSysTclasDelCfm_Evt;
+
+#define send_unifi_sys_tclas_del_cfm(context, pid, p1_status) \
+{ \
+ UnifiSysTclasDelCfm_Evt *evt = (UnifiSysTclasDelCfm_Evt*) osa_malloc(sizeof(UnifiSysTclasDelCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_DEL_CFM_ID);\
+}
+
+#define send_unifi_sys_tclas_del_cfm_external(context, pid, p1_status) \
+{ \
+ UnifiSysTclasDelCfm_Evt *evt = (UnifiSysTclasDelCfm_Evt*) osa_malloc(sizeof(UnifiSysTclasDelCfm_Evt));\
+ evt->status = p1_status;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TCLAS_DEL_CFM_ID);\
+}
+
+/* -------------------------- UNIFI_SYS_TRAFFIC_CLASSIFICATION.request -------------------------- */
+typedef struct UnifiSysTrafficClassificationReq_Evt
+{
+ FsmEvent common;
+ unifi_traffic_type type;
+ uint16 period;
+} UnifiSysTrafficClassificationReq_Evt;
+
+#define send_unifi_sys_traffic_classification_req(context, pid, p1_type, p2_period) \
+{ \
+ UnifiSysTrafficClassificationReq_Evt *evt = (UnifiSysTrafficClassificationReq_Evt*) osa_malloc(sizeof(UnifiSysTrafficClassificationReq_Evt));\
+ evt->type = p1_type;\
+ evt->period = p2_period;\
+ fsm_send_event(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_CLASSIFICATION_REQ_ID);\
+}
+
+#define send_unifi_sys_traffic_classification_req_external(context, pid, p1_type, p2_period) \
+{ \
+ UnifiSysTrafficClassificationReq_Evt *evt = (UnifiSysTrafficClassificationReq_Evt*) osa_malloc(sizeof(UnifiSysTrafficClassificationReq_Evt));\
+ evt->type = p1_type;\
+ evt->period = p2_period;\
+ fsm_send_event_external(context, (FsmEvent*)evt, pid, UNIFI_SYS_TRAFFIC_CLASSIFICATION_REQ_ID);\
+}
+
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_types.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_types.h
new file mode 100644
index 0000000..f7b1a67
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/common/smeio/smeio_fsm_types.h
@@ -0,0 +1,678 @@
+/* This is an autogenerated file from sme___fsm_type_gen */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+/* This is an autogenerated file from sme___fsm_type_gen.pl */
+
+
+#ifndef SME_SIGNALS_XML_TYPES_H
+#define SME_SIGNALS_XML_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* ENUM DEFINITIONS ********************************************************/
+typedef enum unifi_80211_NetworkType
+{
+ unifi_80211_DS = 0x0000,
+ unifi_80211_OFDM24 = 0x0001,
+ unifi_80211_OFDM5 = 0x0002,
+ unifi_80211_Auto = 0x0003
+} unifi_80211_NetworkType;
+
+typedef enum unifi_80211_PrivacyMode
+{
+ unifi_80211_PrivacyDisabled = 0x0000,
+ unifi_80211_PrivacyEnabled = 0x0001
+} unifi_80211_PrivacyMode;
+
+typedef enum unifi_80211dTrustLevel
+{
+ unifi_Trust_Strict = 0x0001,
+ unifi_Trust_Adjunct = 0x0002,
+ unifi_Trust_BSS = 0x0003,
+ unifi_Trust_IBSS = 0x0004,
+ unifi_Trust_MIB = 0x0005,
+ unifi_Trust_Disabled = 0x0006
+} unifi_80211dTrustLevel;
+
+typedef enum unifi_AppValueId
+{
+ unifi_StationMacAddressValue = 0x0000,
+ unifi_PermanentMacAddressValue = 0x0001,
+ unifi_CalibrationDataValue = 0x0002,
+ unifi_ConnectionConfigValue = 0x0003,
+ unifi_AdHocConfigValue = 0x0004,
+ unifi_ConnectionInfoValue = 0x0005,
+ unifi_ConnectionStatsValue = 0x0006,
+ unifi_CoexConfigValue = 0x0007,
+ unifi_CoexInfoValue = 0x0008,
+ unifi_ScanConfigValue = 0x0009,
+ unifi_PowerConfigValue = 0x000A,
+ unifi_VersionsValue = 0x000B,
+ unifi_SMEConfigValue = 0x000C,
+ unifi_HostConfigValue = 0x000D,
+ unifi_MIBConfigValue = 0x000E,
+ unifi_RoamingConfigValue = 0x000F
+} unifi_AppValueId;
+
+typedef enum unifi_AuthMode
+{
+ unifi_80211_AuthOpen = 0x0001,
+ unifi_80211_AuthShared = 0x0002,
+ unifi_8021x_AuthWPA = 0x0004,
+ unifi_8021x_AuthWPAPSK = 0x0008,
+ unifi_8021x_AuthWPA2 = 0x0010,
+ unifi_8021x_AuthWPA2PSK = 0x0020,
+ unifi_8021x_AuthOther1x = 0x0040
+} unifi_AuthMode;
+
+typedef enum unifi_BSSType
+{
+ unifi_Infrastructure = 0x0000,
+ unifi_Adhoc = 0x0001
+} unifi_BSSType;
+
+typedef enum unifi_BasicUsability
+{
+ unifi_Unusable = 0x0000,
+ unifi_Poor = 0x0001,
+ unifi_Satisfactory = 0x0002,
+ unifi_NotConnected = 0x0003
+} unifi_BasicUsability;
+
+typedef enum unifi_CoexDirection
+{
+ unifi_CoexDirectionDot11Input = 0x0001,
+ unifi_CoexDirectionDot11Output = 0x0002
+} unifi_CoexDirection;
+
+typedef enum unifi_CoexScheme
+{
+ unifi_CoexSchemeDisabled = 0x0000,
+ unifi_CoexSchemeCsr = 0x0001,
+ unifi_CoexSchemeCsrChannel = 0x0002,
+ unifi_CoexSchemePTA = 0x0003
+} unifi_CoexScheme;
+
+typedef enum unifi_ControlIndication
+{
+ unifi_Control_Error = 0x0001,
+ unifi_Control_Exit = 0x0002
+} unifi_ControlIndication;
+
+typedef enum unifi_D3AutoScanMode
+{
+ unifi_D3AutoScanMode_Pson = 0x0000,
+ unifi_D3AutoScanMode_Psoff = 0x0001,
+ unifi_D3AutoScanMode_Psauto = 0x0002
+} unifi_D3AutoScanMode;
+
+typedef enum unifi_EncryptionMode
+{
+ unifi_EncryptionCipherNone = 0x0000,
+ unifi_EncryptionCipherPairwiseWep40 = 0x0001,
+ unifi_EncryptionCipherPairwiseWep104 = 0x0002,
+ unifi_EncryptionCipherPairwiseTkip = 0x0004,
+ unifi_EncryptionCipherPairwiseCcmp = 0x0008,
+ unifi_EncryptionCipherGroupWep40 = 0x0010,
+ unifi_EncryptionCipherGroupWep104 = 0x0020,
+ unifi_EncryptionCipherGroupTkip = 0x0040,
+ unifi_EncryptionCipherGroupCcmp = 0x0080
+} unifi_EncryptionMode;
+
+typedef enum unifi_HostPowerMode
+{
+ unifi_HostActive = 0x0000,
+ unifi_HostPowersave = 0x0001,
+ unifi_HostFullPowersave = 0x0002
+} unifi_HostPowerMode;
+
+typedef enum unifi_IEEE80211_Result
+{
+ unifi_IEEE80211_Result_Success = 0x0000,
+ unifi_IEEE80211_Result_UnspecifiedFailure = 0x0001,
+ unifi_IEEE80211_Result_RefusedCapabilitiesMismatch = 0x000A,
+ unifi_IEEE80211_Result_RefusedExternalReason = 0x000C,
+ unifi_IEEE80211_Result_RefusedAPOutOfMemory = 0x0011,
+ unifi_IEEE80211_Result_RefusedBasicRatesMismatch = 0x0012,
+ unifi_IEEE80211_Result_Failure = 0x0020,
+ unifi_IEEE80211_Result_Refused = 0x0025,
+ unifi_IEEE80211_Result_RefusedReasonUnspecified = 0x0025,
+ unifi_IEEE80211_Result_InvalidParameters = 0x0026,
+ unifi_IEEE80211_Result_RejectedWithSuggestedChanges = 0x0027,
+ unifi_IEEE80211_Result_RejectedForDelayPeriod = 0x002F,
+ unifi_IEEE80211_Result_NotAllowed = 0x0030,
+ unifi_IEEE80211_Result_NotPresent = 0x0031,
+ unifi_IEEE80211_Result_NotQSTA = 0x0032,
+ unifi_IEEE80211_Result_Timeout = 0x8000,
+ unifi_IEEE80211_Result_TooManySimultaneousRequests = 0x8001,
+ unifi_IEEE80211_Result_BSSAlreadyStartedOrJoined = 0x8002,
+ unifi_IEEE80211_Result_NotSupported = 0x8003,
+ unifi_IEEE80211_Result_TransmissionFailure = 0x8004,
+ unifi_IEEE80211_Result_RefusedNotAuthenticated = 0x8005,
+ unifi_IEEE80211_Result_ResetRequiredBeforeStart = 0x8006,
+ unifi_IEEE80211_Result_LMInfoUnavailable = 0x8007
+} unifi_IEEE80211_Result;
+
+typedef enum unifi_KeyType
+{
+ unifi_GroupKey = 0x0000,
+ unifi_PairwiseKey = 0x0001
+} unifi_KeyType;
+
+typedef enum unifi_ListAction
+{
+ unifi_ListActionGet = 0x0000,
+ unifi_ListActionAdd = 0x0001,
+ unifi_ListActionRemove = 0x0002,
+ unifi_ListActionFlush = 0x0003
+} unifi_ListAction;
+
+typedef enum unifi_LowPowerMode
+{
+ unifi_LowPowerDisabled = 0x0000,
+ unifi_LowPowerEnabled = 0x0001
+} unifi_LowPowerMode;
+
+typedef enum unifi_MediaStatus
+{
+ unifi_MediaConnected = 0x0000,
+ unifi_MediaDisconnected = 0x0001
+} unifi_MediaStatus;
+
+typedef enum unifi_PacketFilterMode
+{
+ unifi_PacketFilterModeOptOut = 0x0000,
+ unifi_PacketFilterModeOptIn = 0x0003
+} unifi_PacketFilterMode;
+
+typedef enum unifi_PortAction
+{
+ unifi_8021x_PortOpen = 0x0000,
+ unifi_8021x_PortClosedDiscard = 0x0001,
+ unifi_8021x_PortClosedBlock = 0x0002
+} unifi_PortAction;
+
+typedef enum unifi_PowerSaveLevel
+{
+ unifi_PowerSaveLow = 0x0000,
+ unifi_PowerSaveHigh = 0x0001,
+ unifi_PowerSaveMed = 0x0002,
+ unifi_PowerSaveAuto = 0x0003
+} unifi_PowerSaveLevel;
+
+typedef enum unifi_QoSControl
+{
+ unifi_QoSOff = 0x0000,
+ unifi_QoSWMMOn = 0x0001
+} unifi_QoSControl;
+
+typedef enum unifi_QosMode
+{
+ unifi_80211QosOff = 0x0000,
+ unifi_80211QosOn = 0x0001
+} unifi_QosMode;
+
+typedef enum unifi_RadioIF
+{
+ unifi_GHZ_2_4 = 0x0001,
+ unifi_GHZ_5_0 = 0x0002,
+ unifi_GHZ_Both = 0x0003
+} unifi_RadioIF;
+
+typedef enum unifi_ScanType
+{
+ unifi_ScanAll = 0x0000,
+ unifi_ScanActive = 0x0001,
+ unifi_ScanPassive = 0x0002
+} unifi_ScanType;
+
+typedef enum unifi_Status
+{
+ unifi_Success = 0x0000,
+ unifi_Error = 0x0001,
+ unifi_NotFound = 0x0002,
+ unifi_TimedOut = 0x0003,
+ unifi_Cancelled = 0x0004,
+ unifi_InvalidParameter = 0x0005,
+ unifi_NoRoom = 0x0006,
+ unifi_Unsupported = 0x0007,
+ unifi_Unavailable = 0x0008,
+ unifi_WifiOff = 0x0009
+} unifi_Status;
+
+typedef enum unifi_TspecResultCode
+{
+ unifi_Tspec_Result_Success = 0x0000,
+ unifi_Tspec_Result_UnspecifiedFailure = 0x0001,
+ unifi_Tspec_Result_Failure = 0x0002,
+ unifi_Tspec_Result_RefusedReasonUnspecified = 0x0003,
+ unifi_Tspec_Result_Refused = 0x0004,
+ unifi_Tspec_Result_InvalidTspecParameters = 0x0005,
+ unifi_Tspec_Result_InvalidTclasParameters = 0x0006,
+ unifi_Tspec_Result_RejectedWithSuggestedChanges = 0x0007,
+ unifi_Tspec_Result_RejectedForDelayPeriod = 0x0008,
+ unifi_Tspec_Result_NotAllowed = 0x0009,
+ unifi_Tspec_Result_NotPresent = 0x000A,
+ unifi_Tspec_Result_Timeout = 0x000B,
+ unifi_Tspec_Result_NotSupported = 0x000C,
+ unifi_Tspec_Result_AcmMismatch = 0x000D,
+ unifi_Tspec_Result_IeLengthIncorrect = 0x000E
+} unifi_TspecResultCode;
+
+typedef enum unifi_WmmMode
+{
+ unifi_WmmDisabled = 0x0000,
+ unifi_WmmACEnabled = 0x0001,
+ unifi_WmmPSEnabled = 0x0002,
+ unifi_WmmSAEnabled = 0x0004,
+ unifi_WmmEnabled = 0xFFFF
+} unifi_WmmMode;
+
+typedef enum unifi_protocol_direction
+{
+ unifi_traffic_rx = 0x0000,
+ unifi_traffic_tx = 0x0001
+} unifi_protocol_direction;
+
+typedef enum unifi_traffic_configtype
+{
+ unifi_TrafficConfigReset = 0x0000,
+ unifi_TrafficConfigFilter = 0x0001,
+ unifi_TrafficConfigCLS = 0x0002
+} unifi_traffic_configtype;
+
+typedef enum unifi_traffic_packettype
+{
+ unifi_TrafficPacketNone = 0x0000,
+ unifi_TrafficPacketEapol = 0x0001,
+ unifi_TrafficPacketDhcp = 0x0002,
+ unifi_TrafficPacketDhcpAck = 0x0004,
+ unifi_TrafficPacketArp = 0x0008,
+ unifi_TrafficPacketAironet = 0x0010,
+ unifi_TrafficPacketCustom = 0x0020,
+ unifi_TrafficPacketAll = 0x00FF
+} unifi_traffic_packettype;
+
+typedef enum unifi_traffic_type
+{
+ unifi_traffic_occasional = 0x0000,
+ unifi_traffic_bursty = 0x0001,
+ unifi_traffic_periodic = 0x0002,
+ unifi_traffic_continuous = 0x0003
+} unifi_traffic_type;
+
+
+/* CONST TYPES DEFINITIONS ********************************************************/
+#define UNIFI_SAP_API_VERSION_MINOR 209
+#define UNIFI_SAP_API_VERSION_MAJOR 6
+#define UNIFI_SIGNAL_STRENGTH_MAX 10
+#define UNIFI_NETWORK_USEFULNESS_MAX 10
+#define UNIFI_WEP128_KEY_MAX_OCTETS 13
+#define UNIFI_PMKID_KEY_SIZE 16
+#define UNIFI_SCAN_RESULTS_MAX 25
+#define UNIFI_NETWORK_PROVIDER_NAME_MAX_OCTETS 32
+#define UNIFI_SSID_MAX_OCTETS 32
+#define UNIFI_MLME_COMMAND_MAX_OCTETS 32
+#define UNIFI_PMKID_LIST_MAX 4
+#define UNIFI_IPADDRESSV4_BIN_OCTETS 4
+#define UNIFI_WEP64_KEY_MAX_OCTETS 5
+#define UNIFI_SSID_LIST_MAX_OCTETS 5
+#define UNIFI_MAC_ADDRESS_BIN_OCTETS 6
+#define UNIFI_PMKID_CANDIDATES_MAX 8
+
+
+/* POINTER TYPES DEFINITIONS ********************************************************/
+
+/* SIMPLE TYPES DEFINITIONS ********************************************************/
+typedef uint32 unifi_IPV4Address;
+
+typedef char* unifi_String;
+
+
+/* COMPLEX TYPES DEFINITIONS ********************************************************/
+typedef struct unifi_AdHocConfig
+{
+ uint16 atimWindow;
+ uint16 beaconPeriod;
+ uint8 defaultChannelNumber;
+}unifi_AdHocConfig;
+
+typedef struct unifi_ConnectionStats
+{
+ int16 unifiRSSI;
+ int16 unifiSNR;
+ uint8 unifiTxDataRate;
+ uint8 unifiRxDataRate;
+ uint32 dot11RetryCount;
+ uint32 dot11MultipleRetryCount;
+ uint32 dot11ACKFailureCount;
+ uint32 dot11FrameDuplicateCount;
+ uint32 dot11FCSErrorCount;
+ uint32 dot11RTSSuccessCount;
+ uint32 dot11RTSFailureCount;
+ uint32 dot11ReceivedFragmentCount;
+ uint32 dot11TransmittedFragmentCount;
+}unifi_ConnectionStats;
+
+typedef struct unifi_DataBlock
+{
+ uint16 length;
+ uint8 * data;
+}unifi_DataBlock;
+
+typedef struct unifi_DataBlockList
+{
+ uint16 numElements;
+ unifi_DataBlock * datalist;
+}unifi_DataBlockList;
+
+typedef struct unifi_MIBConfig
+{
+ Boolean unifiFixMaxTxDataRate;
+ uint8 unifiFixTxDataRate;
+ uint16 dot11RTSThreshold;
+ uint16 dot11FragmentationThreshold;
+ uint16 dot11CurrentTxPowerLevel;
+}unifi_MIBConfig;
+
+typedef struct unifi_MLME_Command
+{
+ uint8 mlmeCommand[32];
+ uint16 length;
+}unifi_MLME_Command;
+
+typedef struct unifi_MulticastAddressList
+{
+ uint8 numElements;
+ unifi_MACAddress * addresses;
+}unifi_MulticastAddressList;
+
+typedef struct unifi_Pmkid
+{
+ unifi_MACAddress bssid;
+ uint8 pmkid[16];
+}unifi_Pmkid;
+
+typedef struct unifi_PmkidCandidate
+{
+ unifi_MACAddress bssid;
+ Boolean preAuthAllowed;
+}unifi_PmkidCandidate;
+
+typedef struct unifi_PmkidCandidateList
+{
+ uint8 numElements;
+ unifi_PmkidCandidate * pmkidCandidates;
+}unifi_PmkidCandidateList;
+
+typedef struct unifi_PmkidList
+{
+ uint8 numElements;
+ unifi_Pmkid * pmkids;
+}unifi_PmkidList;
+
+typedef struct unifi_RoamingBandData
+{
+ int16 rssiHighThreshold;
+ int16 rssiLowThreshold;
+ int16 snrHighThreshold;
+ int16 snrLowThreshold;
+ uint32 monitorInterval;
+ uint32 monitorWindow;
+ uint8 dot11RetryRatio;
+ uint8 dot11MultipleRetryRatio;
+ uint8 dot11ACKFailureRatio;
+ uint8 dot11FCSErrorRatio;
+ uint8 dot11RTSFailureRatio;
+ uint8 beaconLossThreshold;
+}unifi_RoamingBandData;
+
+typedef struct unifi_RoamingConfig
+{
+ unifi_RoamingBandData roamingBands[3];
+ uint8 lowQualHystWindow;
+ uint8 apBlockTime;
+ uint8 roamMonitorPeriod;
+ uint8 roamNumMaxTh;
+}unifi_RoamingConfig;
+
+typedef struct unifi_SMEConfig
+{
+ Boolean enablePmkidCanditateListIndications;
+ uint8 connectionQualityRssiChangeTrigger;
+ uint8 connectionQualitySnrChangeTrigger;
+ unifi_80211dTrustLevel trustLevel;
+ uint8 countryCode[2];
+ uint16 wmmMode;
+ unifi_RadioIF ifIndex;
+}unifi_SMEConfig;
+
+typedef struct unifi_SSID
+{
+ uint8 ssid[32];
+ uint8 length;
+}unifi_SSID;
+
+typedef struct unifi_ScanConfigData
+{
+ uint16 interval;
+ uint16 validity;
+ uint16 minActiveChannelTime;
+ uint16 maxActiveChannelTime;
+ uint16 minPassiveChannelTime;
+ uint16 maxPassiveChannelTime;
+}unifi_ScanConfigData;
+
+typedef struct unifi_SequenceCount
+{
+ uint8 data[8];
+}unifi_SequenceCount;
+
+typedef struct unifi_TSFTime
+{
+ uint8 data[8];
+}unifi_TSFTime;
+
+typedef struct unifi_Versions
+{
+ uint32 chipId;
+ uint32 chipVersion;
+ uint32 firmwareBuild;
+ uint32 firmwareHip;
+ uint32 driverBuild;
+ uint32 driverHip;
+ uint32 driverApi;
+ uint32 smeBuild;
+ uint32 smeVariant;
+ uint32 smeDriverApi;
+ uint32 smeHip;
+ uint32 smeSapApi;
+ unifi_String smeIdString;
+}unifi_Versions;
+
+typedef struct unifi_traffic_filter
+{
+ uint32 etherType;
+ uint8 ipType;
+ uint32 udpSourcePort;
+ uint32 udpDestPort;
+}unifi_traffic_filter;
+
+typedef struct unifi_traffic_stats
+{
+ uint32 rxFramesNum;
+ uint32 txFramesNum;
+ uint32 rxBytesCount;
+ uint32 txBytesCount;
+ uint8 intervals[11];
+}unifi_traffic_stats;
+
+typedef struct unifi_CoexConfig
+{
+ Boolean coexEnable;
+ Boolean coexAfhChannelEnable;
+ Boolean coexAdvancedEnable;
+ Boolean coexEnableSchemeManagement;
+ unifi_CoexDirection coexDirection;
+ Boolean coexPeriodicWakeHost;
+ uint16 coexTrafficBurstyLatencyMs;
+ uint16 coexTrafficContinuousLatencyMs;
+}unifi_CoexConfig;
+
+typedef struct unifi_CoexInfo
+{
+ Boolean hasTrafficData;
+ unifi_traffic_type currentTrafficType;
+ uint16 currentPeriod;
+ unifi_PowerSaveLevel currentPowerSave;
+ uint16 currentCoexPeriod;
+ uint16 currentCoexLatency;
+ Boolean hasBtDevice;
+ Boolean mibValuesSet;
+ uint16 currentPeriodicPIOInputOffset;
+ uint16 currentPeriodicPIOInputDuration;
+ uint16 currentPeriodicPIOInputPeriod;
+ unifi_CoexScheme currentCoexScheme;
+}unifi_CoexInfo;
+
+typedef struct unifi_ConnectionConfig
+{
+ unifi_SSID ssid;
+ unifi_MACAddress bssid;
+ unifi_BSSType bssType;
+ unifi_80211_PrivacyMode privacyMode;
+ uint16 authMode;
+ uint16 encryptionMode;
+ unifi_DataBlock mlmeAssociateReqInformationElements;
+ uint8 wmmQosInfo;
+ uint8 adhocChannel;
+}unifi_ConnectionConfig;
+
+typedef struct unifi_ConnectionInfo
+{
+ unifi_SSID ssid;
+ unifi_MACAddress bssid;
+ unifi_80211_NetworkType networkType80211;
+ uint8 channelNumber;
+ uint16 channelFrequency;
+ unifi_AuthMode authMode;
+ unifi_RadioIF ifIndex;
+ uint16 atimWindow;
+ uint16 beaconPeriod;
+ unifi_DataBlock assocScanInfoElements;
+ uint16 assocReqCapabilities;
+ uint16 assocReqListenInterval;
+ unifi_MACAddress assocReqApAddress;
+ unifi_DataBlock assocReqInfoElements;
+ unifi_IEEE80211_Result assocRspResult;
+ uint16 assocRspCapabilityInfo;
+ uint16 assocRspAssociationId;
+ unifi_DataBlock assocRspInfoElements;
+}unifi_ConnectionInfo;
+
+typedef struct unifi_HostConfig
+{
+ unifi_HostPowerMode powerMode;
+ uint16 applicationDataPeriodMs;
+}unifi_HostConfig;
+
+typedef struct unifi_Key
+{
+ unifi_KeyType keyType;
+ uint8 keyIndex;
+ Boolean wepTxKey;
+ unifi_SequenceCount keyRsc;
+ Boolean authenticator;
+ unifi_MACAddress address;
+ uint8 keyLength;
+ uint8 key[32];
+}unifi_Key;
+
+typedef struct unifi_PowerConfig
+{
+ unifi_PowerSaveLevel powerSaveLevel;
+ uint16 listenInterval;
+ Boolean rxDtims;
+ unifi_D3AutoScanMode d3autoScanMode;
+}unifi_PowerConfig;
+
+typedef struct unifi_ScanConfig
+{
+ unifi_ScanConfigData scanCfg[4];
+ Boolean enableIndications;
+ uint16 maxResults;
+ int8 highRSSIThreshold;
+ int8 lowRSSIThreshold;
+ int8 deltaRSSIThreshold;
+ int8 highSNRThreshold;
+ int8 lowSNRThreshold;
+ int8 deltaSNRThreshold;
+ unifi_DataBlock passiveChannelList;
+}unifi_ScanConfig;
+
+typedef struct unifi_ScanResult
+{
+ unifi_SSID ssid;
+ unifi_MACAddress bssid;
+ int16 rssi;
+ int16 snr;
+ unifi_RadioIF ifIndex;
+ uint16 beaconPeriod;
+ unifi_TSFTime timestamp;
+ unifi_TSFTime localTime;
+ uint16 channelFrequency;
+ uint16 capabilityInformation;
+ uint8 channelNumber;
+ unifi_BasicUsability usability;
+ unifi_BSSType bssType;
+ unifi_DataBlock informationElements;
+}unifi_ScanResult;
+
+typedef struct unifi_ScanResultList
+{
+ uint16 numElements;
+ unifi_ScanResult * results;
+}unifi_ScanResultList;
+
+typedef struct unifi_traffic_config
+{
+ uint16 packetFilter;
+ unifi_traffic_filter customFilter;
+}unifi_traffic_config;
+
+typedef struct unifi_AppValue
+{
+ unifi_AppValueId id;
+ union
+ {
+ unifi_AdHocConfig adHocConfig;
+ unifi_DataBlock calibrationData;
+ unifi_CoexConfig coexConfig;
+ unifi_CoexInfo coexInfo;
+ unifi_ConnectionConfig connectionConfig;
+ unifi_ConnectionInfo connectionInfo;
+ unifi_ConnectionStats connectionStats;
+ unifi_HostConfig hostConfig;
+ unifi_MIBConfig mibConfig;
+ unifi_MACAddress permanentMacAddress;
+ unifi_PowerConfig powerConfig;
+ unifi_RoamingConfig roamingConfig;
+ unifi_SMEConfig smeConfig;
+ unifi_ScanConfig scanControl;
+ unifi_MACAddress stationMacAddress;
+ unifi_Versions versions;
+ } unifi_Value_union;
+}unifi_AppValue;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*SME_SIGNALS_XML_TYPES_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/bt_sap/bt_sap.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/bt_sap/bt_sap.h
new file mode 100644
index 0000000..5225f92
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/bt_sap/bt_sap.h
@@ -0,0 +1,51 @@
+/* This is an autogenerated file from sap_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __BT_SAP_H__
+#define __BT_SAP_H__
+
+/* ------------------------------------------ */
+extern void unifi_bt_unicore_init_ind(FsmContext* context, uint16 minVersion, uint16 maxVersion,
+ Boolean reply);
+
+extern void unifi_bt_unicore_final_ind(FsmContext* context);
+
+extern void unifi_bt_unicore_ping_ind(FsmContext* context, uint16 tag);
+
+extern void unifi_bt_unicore_pong_ind(FsmContext* context, uint16 tag);
+
+extern void unifi_bt_unicore_pass_sync_start_ind(FsmContext* context, uint16 connectionHandle, uint16 period,
+ uint16 durationMin,
+ uint16 durationMax);
+
+extern void unifi_bt_unicore_pass_sync_change_ind(FsmContext* context, uint16 connectionHandle, uint16 period,
+ uint16 durationMin,
+ uint16 durationMax);
+
+extern void unifi_bt_unicore_pass_sync_stop_ind(FsmContext* context, uint16 connectionHandle);
+
+/* ------------------------------------------ */
+extern void unifi_bt_unicore_init_req(void* context, uint16 minVersion, uint16 maxVersion,
+ Boolean reply);
+
+extern void unifi_bt_unicore_final_req(void* context);
+
+extern void unifi_bt_unicore_ping_req(void* context, uint16 tag);
+
+extern void unifi_bt_unicore_pong_req(void* context, uint16 tag);
+
+extern void unifi_bt_unicore_active_dot11_channel_req(void* context, uint16 channelMhz, uint16 bandwidthMhz);
+
+
+#endif /* __BT_SAP_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/dbg_sap/dbg_sap.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/dbg_sap/dbg_sap.h
new file mode 100644
index 0000000..faec5d6
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/dbg_sap/dbg_sap.h
@@ -0,0 +1,33 @@
+/* This is an autogenerated file from sap_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __DBG_SAP_H__
+#define __DBG_SAP_H__
+
+/* ------------------------------------------ */
+extern void unifi_dbg_set_all_levels_req(FsmContext* context, uint16 level);
+
+extern void unifi_dbg_set_level_req(FsmContext* context, uint16 id, uint16 level);
+
+extern void unifi_dbg_get_level_req(FsmContext* context, uint16 id);
+
+extern void unifi_dbg_exit_req(FsmContext* context);
+
+extern void unifi_dbg_cmd_req(FsmContext* context, unifi_String command);
+
+/* ------------------------------------------ */
+extern void unifi_dbg_get_level_cfm(void* context, uint16 id, uint16 level);
+
+
+#endif /* __DBG_SAP_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap.h
new file mode 100644
index 0000000..61e72bd
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap.h
@@ -0,0 +1,117 @@
+/* This is an autogenerated file from sap_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MGT_SAP_H__
+#define __MGT_SAP_H__
+
+/* ------------------------------------------ */
+extern void unifi_mgt_wifi_on_req(FsmContext* context, const unifi_MACAddress* address, const unifi_DataBlockList* mibFiles);
+
+extern void unifi_mgt_wifi_off_req(FsmContext* context);
+
+extern void unifi_mgt_wifi_flightmode_req(FsmContext* context, const unifi_MACAddress* address, const unifi_DataBlockList* mibFiles);
+
+extern void unifi_mgt_set_value_req(FsmContext* context, const unifi_AppValue* appValue);
+
+extern void unifi_mgt_get_value_req(FsmContext* context, unifi_AppValueId appValueId);
+
+extern void unifi_mgt_mib_set_req(FsmContext* context, const unifi_DataBlock* mibAttribute);
+
+extern void unifi_mgt_mib_get_req(FsmContext* context, const unifi_DataBlock* mibAttribute);
+
+extern void unifi_mgt_mib_get_next_req(FsmContext* context, const unifi_DataBlock* mibAttribute);
+
+extern void unifi_mgt_scan_full_req(FsmContext* context, const unifi_SSID* ssid, Boolean forceScan,
+ unifi_ScanType scanType,
+ const unifi_DataBlock* channelList);
+
+extern void unifi_mgt_scan_results_get_req(FsmContext* context);
+
+extern void unifi_mgt_connect_req(FsmContext* context, const unifi_ConnectionConfig* connectionConfig);
+
+extern void unifi_mgt_disconnect_req(FsmContext* context);
+
+extern void unifi_mgt_multicast_address_req(FsmContext* context, unifi_ListAction action, const unifi_MulticastAddressList* setAddresses);
+
+extern void unifi_mgt_pmkid_req(FsmContext* context, unifi_ListAction action, const unifi_PmkidList* setPmkidList);
+
+extern void unifi_mgt_key_req(FsmContext* context, unifi_ListAction action, const unifi_Key* key);
+
+extern void unifi_mgt_packet_filter_set_req(FsmContext* context, const unifi_DataBlock* filter, unifi_PacketFilterMode mode,
+ unifi_IPV4Address arpFilterAddress);
+
+extern void unifi_mgt_tspec_req(FsmContext* context, unifi_ListAction action, uint32 transactionId,
+ Boolean strict,
+ const unifi_DataBlock* tspec,
+ const unifi_DataBlock* tclas);
+
+/* ------------------------------------------ */
+extern void unifi_mgt_wifi_on_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_wifi_off_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_wifi_off_ind(void* context, unifi_ControlIndication controlIndication);
+
+extern void unifi_mgt_wifi_flightmode_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_set_value_cfm(void* context, unifi_Status status, unifi_AppValueId appValueId);
+
+extern void unifi_mgt_get_value_cfm(void* context, unifi_Status status, const unifi_AppValue* appValue);
+
+extern void unifi_mgt_mib_set_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_mib_get_cfm(void* context, unifi_Status status, const unifi_DataBlock* mibAttributeValue);
+
+extern void unifi_mgt_mib_get_next_cfm(void* context, unifi_Status status, const unifi_DataBlock* mibAttribute);
+
+extern void unifi_mgt_scan_full_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_scan_results_get_cfm(void* context, unifi_Status status, const unifi_ScanResultList* resultsBuffer);
+
+extern void unifi_mgt_scan_result_ind(void* context, const unifi_ScanResult* result);
+
+extern void unifi_mgt_connect_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_media_status_ind(void* context, unifi_MediaStatus mediaStatus, const unifi_ConnectionInfo* connectionInfo);
+
+extern void unifi_mgt_connection_quality_ind(void* context, const unifi_ConnectionStats* connectionStats);
+
+extern void unifi_mgt_disconnect_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_multicast_address_cfm(void* context, unifi_Status status, unifi_ListAction action,
+ const unifi_MulticastAddressList* getAddresses);
+
+extern void unifi_mgt_mic_failure_ind(void* context, Boolean secondFailure, uint16 count,
+ const unifi_MACAddress* address,
+ unifi_KeyType keyType,
+ uint16 keyId,
+ const unifi_SequenceCount* tSC);
+
+extern void unifi_mgt_pmkid_candidate_list_ind(void* context, const unifi_PmkidCandidateList* candidates);
+
+extern void unifi_mgt_pmkid_cfm(void* context, unifi_Status status, unifi_ListAction action,
+ const unifi_PmkidList* getPmkidList);
+
+extern void unifi_mgt_key_cfm(void* context, unifi_Status status, unifi_ListAction action);
+
+extern void unifi_mgt_packet_filter_set_cfm(void* context, unifi_Status status);
+
+extern void unifi_mgt_tspec_cfm(void* context, unifi_Status status, uint32 transactionId,
+ unifi_TspecResultCode tspecResultCode,
+ const unifi_DataBlock* tspec);
+
+extern void unifi_mgt_tspec_ind(void* context, unifi_ListAction action, uint32 transactionId);
+
+
+#endif /* __MGT_SAP_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap_remote_sme_interface.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap_remote_sme_interface.h
new file mode 100644
index 0000000..d4f4ff0
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/mgt_sap/mgt_sap_remote_sme_interface.h
@@ -0,0 +1,36 @@
+/* This is an autogenerated file from sme__sap_remote_sme_interface_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MGT_SAP_REMOTE_OUTPUT_INTERFACE_GEN_H__
+#define __MGT_SAP_REMOTE_OUTPUT_INTERFACE_GEN_H__
+
+#include "abstractions/osa.h"
+#ifdef IPC_IP
+#include "ipc/ipc.h"
+extern ipcConnection* get_mgt_ipc_connection(FsmContext* context);
+#else
+#ifdef IPC_CHARDEVICE
+#include "ipc/ipc.h"
+extern ipcConnection* get_mgt_ipc_connection(FsmContext* context);
+#endif
+#endif
+
+#ifdef REMOTE_MGT_SAP
+extern Boolean remote_mgt_signal_receive(FsmContext* context, uint8* buffer, uint16 size);
+#else
+#define remote_mgt_signal_receive(context, buffer, size) FALSE
+#endif
+
+
+#endif /* __MGT_SAP_REMOTE_OUTPUT_INTERFACE_GEN_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap.h
new file mode 100644
index 0000000..57e87de
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap.h
@@ -0,0 +1,88 @@
+/* This is an autogenerated file from sap_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __SYS_SAP_H__
+#define __SYS_SAP_H__
+
+/* ------------------------------------------ */
+extern void unifi_sys_wifi_on_ind(FsmContext* context, unifi_Status status, const unifi_Versions* versions);
+
+extern void unifi_sys_wifi_on_cfm(FsmContext* context, unifi_Status status);
+
+extern void unifi_sys_wifi_off_ind(FsmContext* context, unifi_ControlIndication controlIndication);
+
+extern void unifi_sys_wifi_off_cfm(FsmContext* context);
+
+extern void unifi_sys_suspend_ind(FsmContext* context, Boolean hardSuspend, Boolean d3Suspend);
+
+extern void unifi_sys_resume_ind(FsmContext* context, Boolean resumePowerMaintained);
+
+extern void unifi_sys_hip_ind(FsmContext* context, const unifi_DataBlock* mlmeCommand, const unifi_DataBlock* dataRef1,
+ const unifi_DataBlock* dataRef2);
+
+extern void unifi_sys_qos_control_cfm(FsmContext* context, unifi_Status status);
+
+extern void unifi_sys_port_configure_cfm(FsmContext* context, unifi_Status status, const unifi_MACAddress* macAddress);
+
+extern void unifi_sys_traffic_sample_ind(FsmContext* context, const unifi_traffic_stats* stats);
+
+extern void unifi_sys_traffic_protocol_ind(FsmContext* context, unifi_traffic_packettype packetType, unifi_protocol_direction direction,
+ const unifi_MACAddress* srcAddress);
+
+extern void unifi_sys_ip_configured_ind(FsmContext* context, Boolean ipConfigured);
+
+extern void unifi_sys_multicast_address_ind(FsmContext* context, unifi_ListAction action, const unifi_MulticastAddressList* setAddresses);
+
+extern void unifi_sys_tclas_add_cfm(FsmContext* context, unifi_Status status);
+
+extern void unifi_sys_tclas_del_cfm(FsmContext* context, unifi_Status status);
+
+/* ------------------------------------------ */
+extern void unifi_sys_wifi_on_req(void* context);
+
+extern void unifi_sys_wifi_on_rsp(void* context, unifi_Status status, const unifi_MACAddress* stationMacAddress);
+
+extern void unifi_sys_wifi_off_req(void* context);
+
+extern void unifi_sys_wifi_off_rsp(void* context);
+
+extern void unifi_sys_suspend_rsp(void* context, unifi_Status status);
+
+extern void unifi_sys_resume_rsp(void* context, unifi_Status status);
+
+extern void unifi_sys_hip_req(void* context, const unifi_DataBlock* mlmeCommand, const unifi_DataBlock* dataRef1,
+ const unifi_DataBlock* dataRef2);
+
+extern void unifi_sys_qos_control_req(void* context, unifi_QoSControl control);
+
+extern void unifi_sys_port_configure_req(void* context, unifi_PortAction uncontrolledPortAction, unifi_PortAction controlledPortAction,
+ const unifi_MACAddress* macAddress);
+
+extern void unifi_sys_configure_power_mode_req(void* context, unifi_LowPowerMode mode, Boolean wakeHost);
+
+extern void unifi_sys_traffic_config_req(void* context, unifi_traffic_configtype type, const unifi_traffic_config* config);
+
+extern void unifi_sys_media_status_req(void* context, unifi_MediaStatus mediaStatus);
+
+extern void unifi_sys_multicast_address_rsp(void* context, unifi_Status status, unifi_ListAction action,
+ const unifi_MulticastAddressList* getAddresses);
+
+extern void unifi_sys_tclas_add_req(void* context, const unifi_DataBlock* tclas);
+
+extern void unifi_sys_tclas_del_req(void* context, const unifi_DataBlock* tclas);
+
+extern void unifi_sys_traffic_classification_req(void* context, unifi_traffic_type type, uint16 period);
+
+
+#endif /* __SYS_SAP_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap_remote_sme_interface.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap_remote_sme_interface.h
new file mode 100644
index 0000000..9babba6
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/saps/sys_sap/sys_sap_remote_sme_interface.h
@@ -0,0 +1,36 @@
+/* This is an autogenerated file from sme__sap_remote_sme_interface_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __SYS_SAP_REMOTE_OUTPUT_INTERFACE_GEN_H__
+#define __SYS_SAP_REMOTE_OUTPUT_INTERFACE_GEN_H__
+
+#include "abstractions/osa.h"
+#ifdef IPC_IP
+#include "ipc/ipc.h"
+extern ipcConnection* get_sys_ipc_connection(FsmContext* context);
+#else
+#ifdef IPC_CHARDEVICE
+#include "ipc/ipc.h"
+extern ipcConnection* get_sys_ipc_connection(FsmContext* context);
+#endif
+#endif
+
+#ifdef REMOTE_SYS_SAP
+extern Boolean remote_sys_signal_receive(FsmContext* context, uint8* buffer, uint16 size);
+#else
+#define remote_sys_signal_receive(context, buffer, size) FALSE
+#endif
+
+
+#endif /* __SYS_SAP_REMOTE_OUTPUT_INTERFACE_GEN_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/lib_sme/sme/sme_top_level_fsm/sme.h b/unifi_hostsw_linux_147/unifi-linux/lib_sme/sme/sme_top_level_fsm/sme.h
new file mode 100644
index 0000000..eed733b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/lib_sme/sme/sme_top_level_fsm/sme.h
@@ -0,0 +1,142 @@
+/** @file sme.h
+ *
+ * SME Interface
+ *
+ * @section LEGAL
+ * CONFIDENTIAL
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source for details on the
+ * license terms.
+ *
+ * @section DESCRIPTION
+ * SME API
+ *
+ ****************************************************************************
+ *
+ * @section REVISION
+ * $Id: //depot/dot11/v6.1/host/lib_sme/sme/sme_top_level_fsm/sme.h#1 $
+ *
+ ****************************************************************************/
+#ifndef SME_H
+#define SME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* PROJECT INCLUDES *********************************************************/
+#include "fsm/fsm.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+
+#include "sys_sap/sys_sap.h"
+#include "mgt_sap/mgt_sap.h"
+
+#include "bt_sap/bt_sap.h"
+
+#include "dbg_sap/dbg_sap.h"
+
+#ifdef SME_SYNC_ACCESS
+#include "sync_access/sync_access.h"
+#endif
+
+#ifdef AMP_PAL_BUILD
+#include "smeio/palio_fsm_types.h"
+#include "pal_ctrl_sap/pal_ctrl_sap.h"
+
+#include "pal_hci_sap/pal_hci_sap_types.h"
+#include "pal_hci_sap/pal_hci_sap.h"
+#endif
+
+/**
+ * @brief
+ * Initialises the SME top level FSM context
+ *
+ * @par Description
+ * This initialises the SME creating all the SME processes
+ * and configuring the SME's FSM context.
+ * This function should only be called once!
+ *
+ * See also sme_shutdown().
+ *
+ * @return
+ * FsmContext* new fsm context
+ */
+extern FsmContext* sme_init(void* externalContext);
+
+/**
+ * @brief
+ * Resets the SME top level FSM context
+ *
+ * @par Description
+ * This function calls sme_shutdown() and then sme_init().
+ * Key data from the SME is saved and the restored before the reset.
+ * This includes calibration data and last connected ap list
+ * This should not be called when fsm_execute() is running
+ *
+ * @return
+ * FsmContext* new fsm context
+ */
+extern FsmContext* sme_reset(FsmContext* context);
+
+
+/**
+ * @brief
+ * Shuts down the SME top level FSM context
+ *
+ * @par Description
+ * This function frees the resources allocated by sme_init() prior to
+ * termination of the program.
+ * This should not be called when fsm_execute() is running
+ *
+ * @return
+ * void
+ */
+extern void sme_shutdown(FsmContext* context);
+
+
+/**
+ * @brief
+ * Executes the sme
+ *
+ * @par Description
+ * Executes the SME context and runs until ALL events processed.
+ * When no more events are left to process then sme_execute() returns a time
+ * specifying when to next call the sme_execute()
+ * Scheduling, threading, blocking and external event notification are outside
+ * the scope of sme_execute().
+ *
+ * @param[in] context : FSM context
+ *
+ * @return
+ * FsmTimerData absolute time + allowed variation for next timeout OR 0xFFFFFFFF if no timers are set
+ */
+extern FsmTimerData sme_execute(FsmContext* context);
+
+/**
+ * @brief
+ * function that installs the sme wakeup function
+ *
+ * @par Description
+ * The installed callback function is called whenever the sme is
+ * needs to wakeup. This will be caused by calls to the sme's
+ * sap api functions.
+ *
+ * @param[in] context : FSM context
+ * @param[in] callback : Callback function pointer
+ *
+ * @return
+ * void
+ */
+extern void sme_install_wakeup_callback(FsmContext* context, FsmExternalWakupCallbackPtr callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SME_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/Android.mk b/unifi_hostsw_linux_147/unifi-linux/os_linux/Android.mk
new file mode 100644
index 0000000..13885ea
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/Android.mk
@@ -0,0 +1,76 @@
+# Copy accross the driver, tools and firmware
+LOCAL_PATH := $(call my-dir)
+
+# Driver module - built beforehand - strip it first
+ALL_PREBUILT += $(TARGET_OUT)/lib/modules/unifi_sdio.ko
+$(TARGET_OUT)/lib/modules/unifi_sdio.ko : $(LOCAL_PATH)/driver/unifi_sdio_stripped.ko | $(ACP)
+ $(transform-prebuilt-to-target)
+
+$(LOCAL_PATH)/driver/unifi_sdio_stripped.ko : $(LOCAL_PATH)/driver/unifi_sdio.ko
+ arm-eabi-strip --strip-unneeded $(dir $@)/unifi_sdio.ko -o $@
+
+# Tools, including udev-helper script
+ALL_PREBUILT += $(TARGET_OUT)/bin/hotplug
+$(TARGET_OUT)/bin/hotplug : $(LOCAL_PATH)/tools/android/hotplug | $(ACP)
+ $(transform-prebuilt-to-target)
+
+ALL_PREBUILT += $(TARGET_OUT)/bin/unififw
+$(TARGET_OUT)/bin/unififw : $(LOCAL_PATH)/tools/android/unififw | $(ACP)
+ $(transform-prebuilt-to-target)
+
+ifneq ($(UNIFI_BUILD_HELPER),true)
+
+# unifi_helper - prebuilt
+ALL_PREBUILT += $(TARGET_OUT)/bin/unifi_helper
+$(TARGET_OUT)/bin/unifi_helper : $(LOCAL_PATH)/tools/android/unifi_helper | $(ACP)
+ $(transform-prebuilt-to-target)
+
+endif
+
+
+# unifi_config application
+include $(CLEAR_VARS)
+LOCAL_SHARED_LIBRARIES := libc libcutils
+LOCAL_SRC_FILES := tools/unifi_config_lib.c \
+ tools/unifi_config.c \
+ tools/android/getsubopt.c
+LOCAL_C_INCLUDES := $(KERNEL_HEADERS) \
+ $(LOCAL_PATH)/../common \
+ $(LOCAL_PATH)/driver \
+ $(LOCAL_PATH)/../lib_sme/common
+LOCAL_MODULE := unifi_config
+include $(BUILD_EXECUTABLE)
+
+# unifi_manager application
+include $(CLEAR_VARS)
+LOCAL_SHARED_LIBRARIES := libc libcutils
+LOCAL_SRC_FILES := tools/unifi_manager.c \
+ tools/mibquery.c \
+ tools/sme_drv.c
+LOCAL_C_INCLUDES := $(KERNEL_HEADERS) \
+ $(LOCAL_PATH)/../common \
+ $(LOCAL_PATH)/driver \
+ $(LOCAL_PATH)/../lib_sme/common
+LOCAL_MODULE := unifi_manager
+include $(BUILD_EXECUTABLE)
+
+# Firmware - originals go in /etc/firmware/unifi-sdio-0
+UNIFI_FW_PATH := unifi-sdio-0
+ALL_PREBUILT += $(TARGET_OUT)/etc/firmware/$(UNIFI_FW_PATH)/loader.xbv
+$(TARGET_OUT)/etc/firmware/$(UNIFI_FW_PATH)/loader.xbv : $(LOCAL_PATH)/../firmware/loader.xbv | $(ACP)
+ $(transform-prebuilt-to-target)
+
+ALL_PREBUILT += $(TARGET_OUT)/etc/firmware/$(UNIFI_FW_PATH)/sta.xbv
+$(TARGET_OUT)/etc/firmware/$(UNIFI_FW_PATH)/sta.xbv : $(LOCAL_PATH)/../firmware/sta.xbv | $(ACP)
+ $(transform-prebuilt-to-target)
+
+# Create a symlink for unifi plugged into second sdio slot
+# /etc/firmware/unifi-sdio-1 -> /etc/firmware/unifi-sdio-0
+SYMLINKS := $(addprefix $(TARGET_OUT),/etc/firmware/unifi-sdio-1)
+$(SYMLINKS): $(TARGET_OUT)/etc/firmware/$(UNIFI_FW_PATH)/sta.xbv
+ @echo "Symlink: $@ -> $(UNIFI_FW_PATH)"
+ @mkdir -p $(dir $@)
+ @rm -rf $@
+ $(hide) ln -sf $(UNIFI_FW_PATH) $@
+
+ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS)
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Kbuild b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Kbuild
new file mode 100644
index 0000000..dfd96e6
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Kbuild
@@ -0,0 +1,287 @@
+# ----------------------------------------------------------------------------
+# FILE: os_linux/Kbuild
+#
+# PURPOSE:
+# Build instructions for UniFi linux driver for 2.6 kernels.
+#
+#
+# Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+# ----------------------------------------------------------------------------
+
+# Read platform config details.
+DRIVERTOP := $(M)/..
+
+
+
+ifeq ($(SDIO_DRIVER),emb)
+
+SDIO_DEFS = -DSDIO_EXPORTS_STRUCT_DEVICE
+SDIO_INCLUDES ?= -I$(SDIODIR)/include
+
+SDIO_OBJS := \
+ sdio_emb.o
+endif
+
+ifeq ($(SDIO_DRIVER),mmc_fs)
+
+SDIO_INCLUDES ?= -I.
+
+SDIO_OBJS := \
+ sdio_mmc_fs.o
+endif
+
+
+ifeq ($(SDIO_DRIVER),mmc)
+
+SDIO_DEFS = -DSDIO_EXPORTS_STRUCT_DEVICE
+
+SDIO_INCLUDES =
+
+SDIO_OBJS := \
+ sdio_mmc.o
+endif
+
+ifeq ($(SDIO_DRIVER),mobstor)
+
+SDIO_INCLUDES ?= -I. -I$(MOBSTOR_DIR)
+
+SDIO_OBJS := \
+ sdio_mobstor.o
+
+endif
+
+
+
+
+# SME releated staff
+ifeq ($(SME), csr)
+
+#SME_INCLUDES += -I$(DRIVERTOP)/smeproxy
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/common
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/saps
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/sme
+
+SME_DEFS = -DCSR_SME_USERSPACE -DCSR_SUPPORT_SME -DREMOTE_SYS_SAP
+OS_OBJS := \
+ sme_csr/sme_userspace.o \
+ sme_csr/sme_sys_sap.o \
+ sme_csr/sme_proxy.o \
+ sme_csr/sys_sap/sys_sap_remoteserver_to_sme_interface.o \
+ sme_csr/sys_sap/sys_sap_build_functions.o \
+ sme_csr/event_pack_unpack/event_pack_unpack.o \
+ sme_osa.o \
+ sme_sys.o \
+ unifi_sme.o \
+ data_tx.o \
+ bh.o drv.o firmware.o \
+ indications.o io.o netdev.o \
+ os.o \
+ ul_int.o \
+ putest.o \
+ unifi_dbg.o
+
+WEXT_OBJS :=
+endif
+
+
+ifeq ($(SME), csr_wext)
+
+#SME_INCLUDES += -I$(DRIVERTOP)/smeproxy
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/common
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/saps
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/sme
+#SME_INCLUDES += -I$(SME_CORE_DIR)
+#SME_INCLUDES += -I$(SME_CORE_DIR)/smeproxy
+#SME_INCLUDES += -I$(SME_CORE_DIR)/saps
+#SME_INCLUDES += -I$(SME_CORE_DIR)/common
+#SME_INCLUDES += -I$(SME_CORE_DIR)/common/abstractions
+
+SME_DEFS = -DCSR_SME_USERSPACE -DCSR_SUPPORT_WEXT -DCSR_SUPPORT_SME \
+ -DREMOTE_SYS_SAP -DREMOTE_MGT_SAP
+OS_OBJS := \
+ sme_csr/sme_userspace.o \
+ sme_csr/sme_sys_sap.o \
+ sme_csr/sme_mgt_sap.o \
+ sme_csr/sme_proxy.o \
+ sme_csr/mgt_sap/mgt_sap_remoteserver_to_sme_interface.o \
+ sme_csr/mgt_sap/mgt_sap_build_functions.o \
+ sme_csr/sys_sap/sys_sap_remoteserver_to_sme_interface.o \
+ sme_csr/sys_sap/sys_sap_build_functions.o \
+ sme_csr/event_pack_unpack/event_pack_unpack.o \
+ sme_osa.o \
+ sme_sys.o \
+ unifi_sme.o \
+ data_tx.o \
+ bh.o drv.o firmware.o \
+ indications.o io.o netdev.o \
+ os.o \
+ ul_int.o \
+ inet.o \
+ putest.o \
+ unifi_dbg.o
+
+WEXT_OBJS := \
+ sme_mgt.o \
+ wext_events.o \
+ sme_wext.o
+endif
+
+
+ifeq ($(SME), native)
+SME_DEFS = -DCSR_NATIVE_LINUX -DCSR_SUPPORT_WEXT
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/common
+OS_OBJS := \
+ sme_native/scan.o \
+ sme_native/mib.o \
+ sme_native/mlme.o \
+ sme_native/autojoin.o \
+ sme_native/sme_native.o \
+ data_tx.o \
+ bh.o drv.o firmware.o \
+ indications.o io.o netdev.o \
+ os.o \
+ ul_int.o \
+ monitor.o \
+ putest.o \
+ unifi_dbg.o
+
+WEXT_OBJS := \
+ wext_events.o \
+ sme_native/wext.o
+
+endif
+
+
+
+ifeq ($(SME), csr_emb)
+
+SME_CORE_DIR = $(DRIVERTOP)/../lib_sme
+
+SME_CODE_DIR = ../../lib_sme
+
+SME_INCLUDES += -I$(DRIVERTOP)/os_embedded/sme_csr
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/common
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/saps
+SME_INCLUDES += -I$(DRIVERTOP)/../lib_sme/sme
+
+SME_OBJS := \
+ sme_osa.o \
+ $(SME_CODE_DIR)/sme/coex_fsm/coex_fsm.o \
+ $(SME_CODE_DIR)/sme/coex_fsm/ta_analyse.o \
+ $(SME_CODE_DIR)/sme/connection_manager_fsm/connection_manager_fsm.o \
+ $(SME_CODE_DIR)/sme/dbg_test_fsm/dbg_fsm.o \
+ $(SME_CODE_DIR)/sme/hip_proxy_fsm/mib_access_fsm.o \
+ $(SME_CODE_DIR)/sme/hip_proxy_fsm/mibdefs.o \
+ $(SME_CODE_DIR)/sme/hip_proxy_fsm/mib_encoding.o \
+ $(SME_CODE_DIR)/sme/hip_proxy_fsm/mib_utils.o \
+ $(SME_CODE_DIR)/sme/hip_proxy_fsm/hip_signal_proxy_fsm.o \
+ $(SME_CODE_DIR)/sme/link_quality_fsm/link_quality_fsm.o \
+ $(SME_CODE_DIR)/sme/network_selector_fsm/network_selector_fsm.o \
+ $(SME_CODE_DIR)/sme/power_manager_fsm/power_manager_fsm.o \
+ $(SME_CODE_DIR)/sme/qos_fsm/qos_fsm.o \
+ $(SME_CODE_DIR)/sme/qos_fsm/qos_tclas.o \
+ $(SME_CODE_DIR)/sme/qos_fsm/qos_tspec.o \
+ $(SME_CODE_DIR)/sme/qos_fsm/qos_block_ack.o \
+ $(SME_CODE_DIR)/sme/regulatory_domain/regulatory_domain.o \
+ $(SME_CODE_DIR)/sme/scan_manager_fsm/scan_manager_fsm.o \
+ $(SME_CODE_DIR)/sme/scan_manager_fsm/scan_results_storage.o \
+ $(SME_CODE_DIR)/sme/security_manager_fsm/security_manager_fsm.o \
+ $(SME_CODE_DIR)/sme/security_manager_fsm/pmk_cache.o \
+ $(SME_CODE_DIR)/sme/sme_configuration/sme_configuration_fsm.o \
+ $(SME_CODE_DIR)/sme/sme_core_fsm/sme_core_fsm.o \
+ $(SME_CODE_DIR)/sme/sme_top_level_fsm/sme_top_level_fsm.o \
+ $(SME_CODE_DIR)/sme/sync_access/sync_access.o \
+ $(SME_CODE_DIR)/sme/unifi_driver_fsm/unifi_driver_fsm.o \
+ $(SME_CODE_DIR)/saps/sys_sap/sme_interface_hip_signal_from_sys_sap.o \
+ $(SME_CODE_DIR)/saps/sys_sap/sme_interface_hip_auto_cfm.o \
+ $(SME_CODE_DIR)/saps/sys_sap/sme_interface_hip_signal_to_sys_sap.o \
+ $(SME_CODE_DIR)/saps/sys_sap/sys_sap__to_sme_interface.o \
+ $(SME_CODE_DIR)/saps/dbg_sap/dbg_sap__to_sme_interface.o \
+ $(SME_CODE_DIR)/saps/mgt_sap/mgt_sap__to_sme_interface.o \
+ $(SME_CODE_DIR)/common/ap_utils/ap_validation.o \
+ $(SME_CODE_DIR)/common/sme_utils/sme_utils.o \
+ $(SME_CODE_DIR)/common/fsm/fsm.o \
+ $(SME_CODE_DIR)/common/fsm/fsm_private.o \
+ $(SME_CODE_DIR)/common/fsm/fsm_debug.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access_ie_trace.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access_dot11n.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access_dot11n_ht_cap.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access_rsn.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access_wmm.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access_wps.o \
+ $(SME_CODE_DIR)/common/ie_access/ie_access_ssid.o \
+ $(SME_CODE_DIR)/common/ie_message_handling/ie_access_associate_req.o \
+ $(SME_CODE_DIR)/common/ie_message_handling/ie_access_scan_req.o \
+ $(SME_CODE_DIR)/common/payload_manager/payload_manager.o \
+ $(SME_CODE_DIR)/common/csr_cstl/csr_list.o \
+ $(SME_CODE_DIR)/common/event_pack_unpack/event_pack_unpack.o \
+ $(SME_CODE_DIR)/common/version/version.o \
+ $(SME_CODE_DIR)/common/sme_trace/sme_trace_common.o \
+ $(SME_CODE_DIR)/common/smeio/smeio_trace_types.o \
+ $(SME_CODE_DIR)/common/smeio/smeio_fsm_trace_events.o \
+ $(SME_CODE_DIR)/common/smeio/smeio_trace_signals.o \
+ inet.o \
+ sme_csr_emb/sme_trace.o \
+ sme_csr_emb/sme_stub.o \
+ sme_csr_emb/sme_emb.o \
+
+
+SME_DEFS = -DCSR_SME_EMB \
+ -DCSR_SUPPORT_SME \
+ -DCSR_SUPPORT_WEXT \
+ -DPACKED_HIP \
+ -DSME_SYNC_ACCESS \
+ -DSME_TRACE_ENABLE \
+ -DSME_PBC_NO_ASSERTS \
+ -DFSM_TRANSITION_LOCK \
+ -DFSM_DEBUG_DUMP \
+ -DFSM_DEBUG \
+ -DSME_TRACE_TYPES_ENABLE
+
+OS_OBJS := \
+ bh.o drv.o firmware.o \
+ data_tx.o \
+ indications.o io.o netdev.o \
+ os.o \
+ ul_int.o \
+ unifi_sme.o \
+ putest.o \
+ unifi_dbg.o
+
+WEXT_OBJS := \
+ sme_mgt.o \
+ sme_sys.o \
+ wext_events.o \
+ sme_wext.o
+
+endif
+
+
+obj-m := unifi_sdio.o
+
+
+unifi_sdio-y := \
+ $(SDIO_OBJS) \
+ sdio_stubs.o \
+ ../../lib_hip/card_sdio.o \
+ ../../lib_hip/card_sdio_mem.o \
+ ../../lib_hip/card_sdio_intr.o \
+ ../../lib_hip/send.o \
+ ../../lib_hip/signals.o \
+ ../../lib_hip/ta_sampling.o \
+ ../../lib_hip/udi.o \
+ ../../lib_hip/unifi_signal_names.o \
+ ../../lib_hip/download.o \
+ ../../lib_hip/xbv.o \
+ ../../lib_hip/chiphelper.o \
+ ../../lib_hip/packing.o \
+ $(OS_OBJS) \
+ $(SME_OBJS) \
+ $(WEXT_OBJS)
+
+
+U_INCLUDES = -I$(DRIVERTOP)/../common -I$(M) $(SDIO_INCLUDES) $(SME_INCLUDES)
+U_DEFINES = -DMODULE -D__KERNEL__ -DUNIFI_DEBUG $(SDIO_DEFS) $(SME_DEFS)
+
+EXTRA_CFLAGS += $(U_DEFINES) $(U_INCLUDES) $(EXTRA_DRV_CFLAGS)
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Makefile b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Makefile
new file mode 100644
index 0000000..7eb02ee
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/Makefile
@@ -0,0 +1,69 @@
+#
+# Makefile for Linux driver
+#
+# Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+#
+# Refer to LICENSE.txt included with this source code for details on
+# the license terms.
+#
+
+ifeq ($(CONFIG),)
+$(error CONFIG not set)
+endif
+
+all: driver tools
+
+include config.$(CONFIG).mk
+
+DRIVERTOP := $(shell pwd)/..
+OSTOP := $(DRIVERTOP)/os_linux/driver
+
+# If the ../packaging/ is missing this is a build from released
+# sources, so build in-place.
+ifeq ($(shell test -d $(DRIVERTOP)/packaging && echo y),y)
+BUILDDIR := $(DRIVERTOP)/../builds/driver/$(CONFIG)
+else
+BUILDDIR := $(DRIVERTOP)/..
+endif
+
+
+driver: sme_common_files buildtree modules
+
+tools: buildtree
+ $(MAKE) -C $(BUILDDIR)/os_linux/tools
+
+install: install_driver install_tools post_install_hook
+
+install_driver: driver install_modules
+
+install_tools: tools
+ $(MAKE) -C $(BUILDDIR)/os_linux/tools install
+
+clean: clean_modules clean_tools
+
+clean_tools:
+ $(MAKE) -C $(BUILDDIR)/os_linux/tools clean
+
+sme_common_files: sme_csr/event_pack_unpack/event_pack_unpack.h sme_csr/event_pack_unpack/event_pack_unpack.c
+
+sme_csr/event_pack_unpack/event_pack_unpack.h: $(DRIVERTOP)/../lib_sme/common/event_pack_unpack/event_pack_unpack.h
+ mkdir -p sme_csr/event_pack_unpack
+ cp -f $< $@
+
+sme_csr/event_pack_unpack/event_pack_unpack.c: $(DRIVERTOP)/../lib_sme/common/event_pack_unpack/event_pack_unpack.c
+ mkdir -p sme_csr/event_pack_unpack
+ cp -f $< $@
+
+buildtree: $(BUILDDIR)
+
+$(BUILDDIR):
+ mkdir -p $(BUILDDIR)
+ find $(BUILDDIR) -type l -exec rm '{}' ';'
+ set -e ; for d in common lib_hip os_linux/driver os_linux/tools lib_sme; do \
+ mkdir -p $(BUILDDIR)/$$d ; \
+ ( cd $(BUILDDIR)/$$d && $(DRIVERTOP)/scripts/lndir $(DRIVERTOP)/../$$d ) ; \
+ done
+
+
+
+.PHONY: post_install_hook
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/bh.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/bh.c
new file mode 100644
index 0000000..570b141
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/bh.c
@@ -0,0 +1,605 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: bh.c
+ *
+ * PURPOSE:
+ * Driver bottom-half.
+ * This provides a bottom-half thread for the driver core.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+
+#define MAX_INIT_ATTEMPTS 4
+
+static void handle_bh_error(unifi_priv_t *priv);
+
+extern int led_mask;
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_start_thread
+ *
+ * Start a new thread.
+ *
+ * Arguments:
+ * priv Pointer to OS driver structure for the device.
+ * thread Pointer to the thread object
+ * func The thread function
+ *
+ * Returns:
+ * 0 on success or else a Linux error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+uf_start_thread(unifi_priv_t *priv, struct uf_thread *thread, int (*func)(void *))
+{
+ if (thread->thread_task != NULL) {
+ unifi_error(priv, "%s thread already started\n", thread->name);
+ return 0;
+ }
+
+ /* Start the kernel thread that handles all h/w accesses. */
+ thread->thread_task = kthread_run(func, priv, thread->name);
+ if (IS_ERR(thread->thread_task)) {
+ return PTR_ERR(thread->thread_task);
+ }
+
+ unifi_trace(priv, UDBG2, "Started %s thread\n", thread->name);
+
+ return 0;
+} /* uf_start_thread() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_stop_thread
+ *
+ * Stops a thread.
+ *
+ * Arguments:
+ * priv Pointer to OS driver structure for the device.
+ * thread Pointer to the thread object
+ *
+ * Returns:
+ *
+ * ---------------------------------------------------------------------------
+ */
+void
+uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread)
+{
+ if (!thread->thread_task) {
+ unifi_notice(priv, "%s thread is already stopped\n", thread->name);
+ return;
+ }
+
+ unifi_trace(priv, UDBG2, "Stopping %s thread\n", thread->name);
+
+ kthread_stop(thread->thread_task);
+ thread->thread_task = NULL;
+
+} /* uf_stop_thread() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_wait_for_thread_to_stop
+ *
+ * Waits until a thread is stopped.
+ *
+ * Arguments:
+ * priv Pointer to OS driver structure for the device.
+ *
+ * Returns:
+ *
+ * ---------------------------------------------------------------------------
+ */
+void
+uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread)
+{
+ /*
+ * kthread_stop() cannot handle the thread exiting while
+ * kthread_should_stop() is false, so sleep until kthread_stop()
+ * wakes us up.
+ */
+ unifi_trace(priv, UDBG2, "%s waiting for the stop signal.\n", thread->name);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!kthread_should_stop()) {
+ unifi_trace(priv, UDBG2, "%s schedule....\n", thread->name);
+ schedule();
+ }
+
+ thread->thread_task = NULL;
+ unifi_trace(priv, UDBG2, "%s exiting....\n", thread->name);
+} /* uf_wait_for_thread_to_stop() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * bh_thread_function
+ *
+ * All hardware access happens in this thread.
+ * This means there is no need for locks on the hardware and we don't need
+ * to worry about reentrancy with the SDIO library.
+ *
+ * Arguments:
+ * arg Pointer to OS driver structure for the device.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * When the bottom half of the driver needs to process signals, events,
+ * or simply the host status (i.e sleep mode), it invokes unifi_run_bh().
+ * Since we need all SDIO transaction to be in a single thread, the
+ * unifi_run_bh() will store the reason any wake up this thread to process it.
+ *
+ * ---------------------------------------------------------------------------
+ */
+static int
+bh_thread_function(void *arg)
+{
+ unifi_priv_t *priv = (unifi_priv_t *)arg;
+ int r;
+ long ret;
+ long timeout, t;
+ struct uf_thread *this_thread;
+
+ unifi_trace(priv, UDBG2, "bh_thread_function starting\n");
+
+ this_thread = &priv->bh_thread;
+
+ t = timeout = 0;
+ while (!kthread_should_stop()) {
+ /* wait until an error occurs, or we need to process something. */
+ unifi_trace(priv, UDBG3, "bh_thread goes to sleep.\n");
+
+ if (timeout > 0) {
+ /* Convert t in ms to jiffies */
+ t = msecs_to_jiffies(timeout);
+ ret = wait_event_interruptible_timeout(this_thread->wakeup_q,
+ (this_thread->wakeup_flag && !this_thread->block_thread) ||
+ kthread_should_stop(),
+ t);
+ timeout = (ret > 0) ? jiffies_to_msecs(ret) : 0;
+ } else {
+ ret = wait_event_interruptible(this_thread->wakeup_q,
+ (this_thread->wakeup_flag && !this_thread->block_thread) ||
+ kthread_should_stop());
+ }
+
+ if (kthread_should_stop()) {
+ unifi_trace(priv, UDBG2, "bh_thread: signalled to exit\n");
+ break;
+ }
+
+ if (ret < 0) {
+ unifi_notice(priv,
+ "bh_thread: wait_event returned %d, thread will exit\n",
+ ret);
+ uf_wait_for_thread_to_stop(priv, this_thread);
+ break;
+ }
+
+ this_thread->wakeup_flag = 0;
+
+ unifi_trace(priv, UDBG3, "bh_thread calls unifi_bh().\n");
+
+ uf_sdio_claim(priv->sdio);
+ r = unifi_bh(priv->card, &timeout);
+ uf_sdio_release(priv->sdio);
+ if (r == -ENODEV) {
+ uf_wait_for_thread_to_stop(priv, this_thread);
+ break;
+ }
+ if (r < 0) {
+ /* Errors must be delivered to the error task */
+ handle_bh_error(priv);
+ }
+ }
+
+ /*
+ * Interrupts might be enabled here, (unifi_bh enables them)
+ * so we need to disable interrupts before return.
+ */
+ uf_sdio_claim(priv->sdio);
+ unifi_sdio_enable_interrupt(priv->sdio, 0);
+ uf_sdio_release(priv->sdio);
+
+ unifi_trace(priv, UDBG2, "bh_thread exiting....\n");
+ return 0;
+} /* bh_thread_function() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_init_bh
+ *
+ * Starts the bottom half of the driver.
+ * All we need to do here is start the I/O bh thread.
+ *
+ * Arguments:
+ * priv Pointer to OS driver structure for the device.
+ *
+ * Returns:
+ * 0 on success or else a Linux error code.
+ *
+ * Notes:
+ * This is the first function in the sequence that the SME
+ * (or helper application) need to call in order to initialize unifi.
+ * ---------------------------------------------------------------------------
+ */
+int
+uf_init_bh(unifi_priv_t *priv)
+{
+ /* Enable mlme interface. */
+ priv->io_aborted = 0;
+
+
+ return uf_start_thread(priv, &priv->bh_thread, bh_thread_function);
+} /* uf_init_bh() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * handle_bh_error
+ *
+ * This function reports an error to the SME (or the helper app).
+ * Normally, the SME will try to reset the device and go through
+ * the initialisation of the UniFi.
+ *
+ * Arguments:
+ * priv Pointer to OS driver structure for the device.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * ---------------------------------------------------------------------------
+ */
+static void
+handle_bh_error(unifi_priv_t *priv)
+{
+ u8 conf_param = CONFIG_IND_ERROR;
+
+
+ /* Block unifi_run_bh() until the error has been handled. */
+ priv->bh_thread.block_thread = 1;
+ /* Consider UniFi to be uninitialised */
+ priv->init_progress = UNIFI_INIT_NONE;
+
+ /* Stop the network traffic */
+ if (priv->netdev_registered == 1) {
+ netif_carrier_off(priv->netdev);
+ }
+
+#ifdef CSR_NATIVE_LINUX
+ /* Force any client waiting on an mlme_wait_for_reply() to abort. */
+ unifi_abort_mlme(priv);
+#endif /* CSR_NATIVE_LINUX */
+
+ unifi_error(priv, "handle_bh_error: fatal error is reported to the SME.\n");
+ /* Notify the clients (SME or unifi_manager) for the error. */
+ ul_log_config_ind(priv, &conf_param, sizeof(u8));
+
+} /* handle_bh_error() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_run_bh
+ *
+ * The bottom half of the driver calls this function when
+ * it wants to process anything that requires access to unifi.
+ * We need to call unifi_bh() which in this implementation is done
+ * by waking up the manager thread.
+ *
+ * Arguments:
+ * ospriv Pointer to OS driver structure for the device.
+ *
+ * Returns:
+ * 0 on success or else a Linux error code.
+ *
+ * Notes:
+ * ---------------------------------------------------------------------------
+ */
+int unifi_run_bh(void *ospriv)
+{
+ unifi_priv_t *priv = ospriv;
+
+ /*
+ * If an error has occured, we discard silently all messages from the bh
+ * until the error has been processed and the unifi has been reinitialised.
+ */
+ if (priv->bh_thread.block_thread == 1) {
+ unifi_trace(priv, UDBG3, "unifi_run_bh: discard message.\n");
+ return -EIO;
+ }
+
+ priv->bh_thread.wakeup_flag = 1;
+ /* wake up I/O thread */
+ wake_up_interruptible(&priv->bh_thread.wakeup_q);
+
+ return 0;
+} /* unifi_run_bh() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_init_hw
+ *
+ * Resets hardware, downloads and initialised f/w.
+ * This function will retry to initialise UniFi if unifi_init_card()
+ * returns an error.
+ *
+ * Arguments:
+ * ospriv Pointer to OS driver structure for the device.
+ *
+ * Returns:
+ * O on success, non-zero otherwise.
+ *
+ * ---------------------------------------------------------------------------
+ */
+int
+uf_init_hw(unifi_priv_t *priv)
+{
+ int attempts = 0;
+ int r = -1;
+ int priv_instance;
+
+ priv_instance = unifi_find_priv(priv);
+ if (priv_instance == -1) {
+ unifi_warning(priv, "uf_init_hw: Unknown priv instance, will use fw_init[0]\n");
+ priv_instance = 0;
+ }
+
+ while (1) {
+ if (attempts > MAX_INIT_ATTEMPTS) {
+ unifi_error(priv, "Failed to initialise UniFi after %d attempts, "
+ "giving up.\n",
+ attempts);
+ break;
+ }
+ attempts++;
+
+ unifi_info(priv, "Initialising UniFi, attempt %d\n", attempts);
+
+ if (fw_init[priv_instance] > 0) {
+ unifi_notice(priv, "f/w init prevented by module parameter\n");
+ break;
+ } else if (fw_init[priv_instance] == 0) {
+ fw_init[priv_instance] ++;
+ }
+
+ /*
+ * Initialise driver core. This will perform a reset of UniFi
+ * internals, but not the SDIO CCCR.
+ */
+ uf_sdio_claim(priv->sdio);
+ r = unifi_init_card(priv->card, led_mask);
+ uf_sdio_release(priv->sdio);
+ if (r == -ENODEV) {
+ break;
+ }
+ if (r == -ENODATA) {
+ unifi_error(priv, "Firmware file required, but not found.\n");
+ break;
+ }
+ if (r < 0) {
+ /* failed. Reset h/w and try again */
+ unifi_error(priv, "Failed to initialise UniFi chip.\n");
+ continue;
+ }
+
+ /* Enabled deep sleep signaling */
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_ENABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+
+ /* Enable bh processing */
+ priv->bh_thread.block_thread = 0;
+
+ /* Get the version information from the core */
+ unifi_card_info(priv->card, &priv->card_info);
+
+ return r;
+ }
+
+ return r;
+
+} /* uf_init_hw */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * F/W download. Part of the HIP driver API
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_fw_read_start
+ *
+ * Returns a structure to be passed in unifi_fw_read().
+ * This structure is an OS specific description of the f/w file.
+ * In the linux implementation it is a buffer with the f/w and its' length.
+ * The HIP driver calls this functions to request for the loader or
+ * the firmware file.
+ * The structure pointer can be freed when unifi_fw_read_stop() is called.
+ *
+ * Arguments:
+ * ospriv Pointer to driver context.
+ * is_fw Flag to indicate whether it is the f/w or the loader
+ *
+ * Returns:
+ * O on success, non-zero otherwise.
+ *
+ * ---------------------------------------------------------------------------
+ */
+void*
+unifi_fw_read_start(void *ospriv, int is_fw)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+
+ func_enter();
+
+ if (is_fw == UNIFI_FW_LOADER) {
+ /* Set up callback struct for readfunc() */
+ if (priv->fw_loader.dl_data != NULL) {
+ func_exit();
+ return &priv->fw_loader;
+ }
+
+ } else if (is_fw == UNIFI_FW_STA) {
+ /* Set up callback struct for readfunc() */
+ if (priv->fw_sta.dl_data != NULL) {
+ func_exit();
+ return &priv->fw_sta;
+ }
+
+ } else {
+ unifi_error(priv, "downloading firmware... unknown request: %d\n", is_fw);
+ }
+
+ func_exit();
+ return NULL;
+} /* unifi_fw_read_start() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_fw_read_stop
+ *
+ * Called when the HIP driver has finished using the loader or
+ * the firmware file.
+ * The dlpriv pointer can be freed now.
+ *
+ * Arguments:
+ * ospriv Pointer to driver context.
+ * dlpriv The pointer returned by unifi_fw_read_start()
+ *
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_fw_read_stop(void *ospriv, void *dlpriv)
+{
+ /* EMPTY */
+} /* unifi_fw_read_stop() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_fw_read
+ *
+ * The HIP driver calls this function to ask for a part of the loader or
+ * the firmware file.
+ *
+ * Arguments:
+ * ospriv Pointer to driver context.
+ * arg The pointer returned by unifi_fw_read_start().
+ * offset The offset in the file to return from.
+ * buf A buffer to store the requested data.
+ * len The size of the buf and the size of the requested data.
+ *
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_fw_read(void *ospriv, void *arg, int offset, void *buf, int len)
+{
+ const struct dlpriv *dlpriv = arg;
+
+ if (offset >= dlpriv->dl_len) {
+ /* at end of file */
+ return 0;
+ }
+
+ if ((offset + len) > dlpriv->dl_len) {
+ /* attempt to read past end of file */
+ return -1;
+ }
+
+ memcpy(buf, dlpriv->dl_data+offset, len);
+
+ return len;
+
+} /* unifi_fw_read() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Suspend / Resume. Part of the HIP driver API
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_suspend
+ *
+ * Handles a suspend request from the SDIO driver.
+ *
+ * Arguments:
+ * ospriv Pointer to OS driver context.
+ *
+ * ---------------------------------------------------------------------------
+ */
+void unifi_suspend(void *ospriv)
+{
+ unifi_priv_t *priv = ospriv;
+
+ if (priv->netdev_registered == 1) {
+ /* Stop network traffic. */
+ netif_carrier_off(priv->netdev);
+ UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev);
+ }
+
+ sme_sys_suspend(priv);
+} /* unifi_suspend() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_resume
+ *
+ * Handles a resume request from the SDIO driver.
+ *
+ * Arguments:
+ * ospriv Pointer to OS driver context.
+ *
+ * ---------------------------------------------------------------------------
+ */
+void unifi_resume(void *ospriv)
+{
+ unifi_priv_t *priv = ospriv;
+ int r;
+
+ r = sme_sys_resume(priv);
+ if (r) {
+ unifi_error(priv, "Failed to resume UniFi\n");
+ }
+
+} /* unifi_resume() */
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/build b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/build
new file mode 100755
index 0000000..823aa9b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/build
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+os_top=$(dirname $0)
+config=$1 ; shift
+config_file=$os_top/config.$config.mk
+
+if [ "x$config" = "x" ]; then
+ echo "Usage: $0 <config> [<make target/option>]..." >&2
+ exit 1
+fi
+
+if [ ! -e $config_file ]; then
+ echo "Configuration '$config' ($config_file) does not exist." >&2
+ exit 1
+fi
+
+exec make -C ${os_top} CONFIG=$config "$@"
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.3dlabs.mk b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.3dlabs.mk
new file mode 100644
index 0000000..70fe8b8
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.3dlabs.mk
@@ -0,0 +1,20 @@
+#
+# Make configuration file for 3D Labs DMS-05 EVM with
+# mobstor SDIO driver.
+#
+# Assumes that the mobstor package are unpacked in /opt/s5toolsl21/mobstor
+# and the mobstor header files are in /opt/s5toolsl21/mobstor/src
+#
+ARCH := arm
+CROSS_COMPILE := /opt/s5toolsl21/lx_eabi/bin/arm-3d-linux-gnueabi-
+KDIR := /opt/s5toolsl21/evmrelr2_eabi/release/src.build/
+
+MOBSTOR_DIR := /opt/s5toolsl21/mobstor/src
+export MOBSTOR_DIR
+
+#EXTRA_DRV_CFLAGS := -DUNIFI_NET_NAME=\"wifi\"
+#export EXTRA_DRV_CFLAGS
+
+SDIO_DRIVER := mobstor
+
+include config.generic.mk
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.android-arm.mk b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.android-arm.mk
new file mode 100644
index 0000000..181f063
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.android-arm.mk
@@ -0,0 +1,9 @@
+ARCH := arm
+TMP_DIR := $(PWD)
+SDIO_DRIVER := mmc
+KDIR := $(TMP_DIR)/../../../../../kernel
+CROSS_COMPILE := $(TMP_DIR)/../../../../../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-
+EXTRA_DRV_CFLAGS := -DUNIFI_NET_NAME=\"wlan\" -DANDROID_BUILD
+export EXTRA_DRV_CFLAGS
+
+include config.generic.mk
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.arm-linux.mk b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.arm-linux.mk
new file mode 100644
index 0000000..c06818b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.arm-linux.mk
@@ -0,0 +1,8 @@
+ARCH := arm
+CROSS_COMPILE := arm-linux-
+
+ifeq ($(KDIR),)
+$(error Set KDIR to the kernel tree to build against)
+endif
+
+include config.generic.mk
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.generic.mk b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.generic.mk
new file mode 100644
index 0000000..5a00312
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/config.generic.mk
@@ -0,0 +1,41 @@
+KDIR ?= /lib/modules/$(shell uname -r)/build
+SDIO_DRIVER ?= emb
+SME ?= csr_wext
+
+ifeq ($(SDIO_DRIVER),emb)
+ifeq ($(SDIODIR),)
+$(error Set SDIODIR to the sdioemb driver path e.g. ../../sdioemb )
+endif
+endif
+
+modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR)/os_linux/driver \
+ O=$(O) V=$(V)
+
+install_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR)/os_linux/driver modules_install INSTALL_MOD_PATH=$(DESTDIR) \
+ O=$(O) V=$(V)
+
+# Kbuild's clean target doesn't play nicely with our Kbuild file:
+# ../lib_hip/ isn't cleaned because it's above M; and .config isn't
+# included so SDIO_PLATFORM isn't defined.
+clean_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR)/os_linux/driver clean \
+ O=$(O) V=$(V) SDIO_PLATFORM=unused
+ rm -f $(BUILDDIR)/lib_hip/*.o $(BUILDDIR)/lib_hip/.*.o.cmd
+ rm -f $(BUILDDIR)/os_linux/driver/sme_csr/event_pack_unpack/event_pack_unpack.c
+ rm -f $(BUILDDIR)/os_linux/driver/sme_csr/event_pack_unpack/event_pack_unpack.h
+ rm -f $(BUILDDIR)/os_linux/driver/Module.markers
+ rm -f $(BUILDDIR)/os_linux/driver/modules.order
+
+ifneq ($(CROSS_COMPILE),)
+export CROSS_COMPILE
+endif
+
+ifneq ($(ARCH),)
+export ARCH
+endif
+
+export SDIO_DRIVER
+export SDIODIR
+export SME
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/data_tx.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/data_tx.c
new file mode 100644
index 0000000..0426133
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/data_tx.c
@@ -0,0 +1,138 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: data_tx.c
+ *
+ * PURPOSE:
+ * This file provides functions to send data requests to the UniFi.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Data transport signals.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_mlme_eapol
+ *
+ * Send a EAP data packet in a MLME-EAPOL signal to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * pcli Pointer to context of calling process
+ * sig Pointer to a signal containing a MLME-EAPOL.req
+ * bulkdata Pointer to a bulk data structure, describing
+ * the data to be sent.
+ *
+ * Returns:
+ * 0 on success
+ * -1 if an error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_mlme_eapol(unifi_priv_t *priv, ul_client_t *pcli,
+ CSR_SIGNAL *sig, const bulk_data_param_t *bulkdata)
+{
+ int r;
+
+ sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
+ sig->SignalPrimitiveHeader.SenderProcessId = pcli->sender_id;
+
+ /* Send the signal to UniFi */
+ r = ul_send_signal_unpacked(priv, sig, bulkdata);
+ if (r) {
+ unifi_error(priv, "Error queueing CSR_MLME_EAPOL_REQUEST signal\n");
+ return -1;
+ }
+
+ /*
+ * We do not advance the sequence number of the last sent signal
+ * because we will not wait for a response from UniFi.
+ */
+
+ return 0;
+} /* unifi_mlme_eapol() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_ma_unitdata
+ * unifi_ds_unitdata
+ *
+ * Send a UNITDATA signal to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * pcli Pointer to context of calling process
+ * sig Pointer to a signal containing a MA_UNITDATA
+ * or DS_UNITDATA request structure to send.
+ * bulkdata Pointer a to bulk data structure, describing
+ * the data to be sent.
+ *
+ * Returns:
+ * 0 on success
+ * -1 if an error occurred
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_ma_unitdata(unifi_priv_t *priv, ul_client_t *pcli,
+ CSR_SIGNAL *sig, const bulk_data_param_t *bulkdata)
+{
+ int r;
+
+ sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
+ sig->SignalPrimitiveHeader.SenderProcessId = pcli->sender_id;
+
+ /* Send the signal to UniFi */
+ r = ul_send_signal_unpacked(priv, sig, bulkdata);
+ if (r) {
+ unifi_error(priv, "Error queueing CSR_MA_UNITDATA_REQUEST signal\n");
+ return -1;
+ }
+
+ /*
+ * We do not advance the sequence number of the last sent signal
+ * because we will not wait for a response from UniFi.
+ */
+
+ return 0;
+} /* unifi_ma_unitdata() */
+
+int
+unifi_ds_unitdata(unifi_priv_t *priv, ul_client_t *pcli,
+ CSR_SIGNAL *sig, const bulk_data_param_t *bulkdata)
+{
+ int r;
+
+ sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
+ sig->SignalPrimitiveHeader.SenderProcessId = pcli->sender_id;
+
+ /* Send the signal to UniFi */
+ r = ul_send_signal_unpacked(priv, sig, bulkdata);
+ if (r) {
+ unifi_error(priv, "Error queueing CSR_DS_UNITDATA_REQUEST signal\n");
+ return -1;
+ }
+
+ /*
+ * We do not advance the sequence number of the last sent signal
+ * because we will not wait for a response from UniFi.
+ */
+
+ return 0;
+} /* unifi_ds_unitdata() */
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/drv.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/drv.c
new file mode 100644
index 0000000..eff0ccb
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/drv.c
@@ -0,0 +1,1773 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: drv.c
+ *
+ * PURPOSE:
+ * Conventional device interface for debugging/monitoring of the
+ * driver and h/w using unicli. This interface is also being used
+ * by the SME and the helper apps.
+ *
+ * We use a different ProcessId value for each client instance when
+ * sending signals.
+ * The net device will use 0xC001.
+ * UDI clients will use 0xC100-0xC10F for the first chip, 0xC110-0xC11F
+ * for the second chip etc.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <asm/uaccess.h>
+
+#include <driver/unifiversion.h>
+#include "unifi_priv.h"
+#include <driver/conversions.h>
+
+#include "event_pack_unpack/event_pack_unpack.h"
+
+/* Module parameter variables */
+int buswidth = 0; /* 0 means use default, values 1,4 */
+int sdio_clock = 25000; /* kHz */
+int unifi_debug = 0;
+/*
+ * fw_init prevents f/w initialisation on error.
+ * Unless necessary, avoid usage in the CSR_SME_EMB build because it prevents
+ * UniFi initialisation after getting out of suspend and also leaves
+ * UniFi powered when the module unloads.
+ */
+int fw_init[MAX_UNIFI_DEVS] = {-1, -1};
+int use_5g = 0;
+int led_mask = 0; /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */
+int disable_hw_reset = 0;
+#ifdef CSR_SME_EMB
+int sme_debug = 0;
+#endif
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+int tl_80211d = (int)unifi_Trust_MIB;
+#endif
+
+
+MODULE_DESCRIPTION("CSR UniFi (SDIO)");
+
+module_param(buswidth, int, S_IRUGO|S_IWUSR);
+module_param(sdio_clock, int, S_IRUGO|S_IWUSR);
+module_param(unifi_debug, int, S_IRUGO|S_IWUSR);
+module_param_array(fw_init, int, NULL, S_IRUGO|S_IWUSR);
+module_param(use_5g, int, S_IRUGO|S_IWUSR);
+module_param(led_mask, int, S_IRUGO|S_IWUSR);
+#ifdef CSR_SME_EMB
+module_param(sme_debug, int, S_IRUGO|S_IWUSR);
+#endif /* CSR_SME_EMB */
+module_param(disable_hw_reset, int, S_IRUGO|S_IWUSR);
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+module_param(tl_80211d, int, S_IRUGO|S_IWUSR);
+#endif
+
+MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode");
+MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 25 MHz)");
+MODULE_PARM_DESC(unifi_debug, "Diagnostic reporting level");
+MODULE_PARM_DESC(fw_init, "Set to 0 to prevent f/w initialization on error");
+MODULE_PARM_DESC(use_5g, "Use the 5G (802.11a) radio band");
+MODULE_PARM_DESC(led_mask, "LED mask flags");
+#ifdef CSR_SME_EMB
+MODULE_PARM_DESC(sme_debug, "SME diagnostic reporting level");
+#endif
+MODULE_PARM_DESC(disable_hw_reset, "Set to 1 to disable hardware reset");
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+MODULE_PARM_DESC(tl_80211d, "802.11d Trust Level (1-6, default = 5)");
+#endif
+
+
+/* Callback for event logging to UDI clients */
+static void udi_log_event(ul_client_t *client,
+ u8 *signal, int signal_len,
+ const bulk_data_param_t *bulkdata,
+ int dir);
+
+static void udi_set_log_filter(ul_client_t *pcli,
+ unifiio_filter_t *udi_filter);
+
+
+/* Mutex to protect access to priv->sme_cli */
+DECLARE_MUTEX(udi_mutex);
+
+static const char*
+trace_putest_cmdid(unifi_putest_command_t putest_cmd)
+{
+ switch (putest_cmd)
+ {
+ case UNIFI_PUTEST_START:
+ return "START";
+ case UNIFI_PUTEST_STOP:
+ return "STOP";
+ case UNIFI_PUTEST_SET_SDIO_CLOCK:
+ return "SET CLOCK";
+ case UNIFI_PUTEST_CMD52_READ:
+ return "CMD52R";
+ case UNIFI_PUTEST_CMD52_WRITE:
+ return "CMD52W";
+ case UNIFI_PUTEST_DL_FW:
+ return "D/L FW";
+ default:
+ return "ERROR: unrecognised command";
+ }
+ }
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_open
+ * unifi_release
+ *
+ * Open and release entry points for the UniFi debug driver.
+ *
+ * Arguments:
+ * Normal linux driver args.
+ *
+ * Returns:
+ * Linux error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_open(struct inode *inode, struct file *file)
+{
+ int devno;
+ unifi_priv_t *priv;
+ ul_client_t *udi_cli;
+
+ func_enter();
+
+ devno = MINOR(inode->i_rdev) >> 1;
+
+ /*
+ * Increase the ref_count for the char device clients.
+ * Make sure you call unifi_put_instance() to decreace it if
+ * unifi_open returns an error.
+ */
+ priv = unifi_get_instance(devno);
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_open: No device present\n");
+ func_exit();
+ return -ENODEV;
+ }
+
+ /* Register this instance in the client's list. */
+ /* The minor number determines the nature of the client (Unicli or SME). */
+ if (MINOR(inode->i_rdev) & 0x1) {
+ udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event);
+ if (udi_cli == NULL) {
+ /* Too many clients already using this device */
+ unifi_error(priv, "Too many clients already open\n");
+ unifi_put_instance(devno);
+ func_exit();
+ return -ENOSPC;
+ }
+ unifi_trace(priv, UDBG1, "Client is registered to /dev/unifiudi%d\n", devno);
+ } else {
+ /*
+ * Even-numbered device nodes are the control application.
+ * This is the userspace helper containing SME or
+ * unifi_manager.
+ */
+
+ down(&udi_mutex);
+
+#ifdef CSR_SME_USERSPACE
+ /* Check if a config client is already attached */
+ if (priv->sme_cli) {
+ up(&udi_mutex);
+ unifi_put_instance(devno);
+
+ unifi_info(priv, "There is already a configuration client using the character device\n");
+ func_exit();
+ return -EBUSY;
+ }
+#endif /* CSR_SME_USERSPACE */
+
+#ifdef CSR_SUPPORT_SME
+ udi_cli = ul_register_client(priv,
+ CLI_USING_WIRE_FORMAT | CLI_SME_USERSPACE,
+ sme_log_event);
+#else
+ /* Config client for native driver */
+ udi_cli = ul_register_client(priv,
+ 0,
+ sme_native_log_event);
+#endif
+ if (udi_cli == NULL) {
+ /* Too many clients already using this device */
+ up(&udi_mutex);
+ unifi_put_instance(devno);
+
+ unifi_error(priv, "Too many clients already open\n");
+ func_exit();
+ return -ENOSPC;
+ }
+
+#ifndef CSR_SME_EMB
+ /*
+ * Fill-in the pointer to the configuration client.
+ * This is the SME userspace helper or unifi_manager.
+ * Not used in the SME embedded version.
+ */
+ unifi_trace(priv, UDBG1, "SME client (id:%d s:0x%X) is registered\n",
+ udi_cli->client_id, udi_cli->sender_id);
+ /* Store the SME UniFi Linux Client */
+ if (priv->sme_cli == NULL) {
+ priv->sme_cli = udi_cli;
+ }
+#endif
+
+ up(&udi_mutex);
+ }
+
+
+ /*
+ * Store the pointer to the client.
+ * All char driver's entry points will pass this pointer.
+ */
+ file->private_data = udi_cli;
+
+ func_exit();
+ return 0;
+} /* unifi_open() */
+
+
+
+static int
+unifi_release(struct inode *inode, struct file *filp)
+{
+ ul_client_t *udi_cli = (void*)filp->private_data;
+ int devno;
+ unifi_priv_t *priv;
+
+ func_enter();
+
+ priv = unifi_find_instance(udi_cli->instance);
+ if (!priv) {
+ unifi_error(priv, "unifi_close: instance for device not found\n");
+ return -ENODEV;
+ }
+
+
+ /* Even device nodes are the config client (i.e. SME or unifi_manager) */
+ if ((MINOR(inode->i_rdev) & 0x1) == 0) {
+
+#ifndef CSR_SME_EMB
+ if (priv->sme_cli != udi_cli) {
+ unifi_notice(priv, "Surprise closing config device: not the sme client\n");
+ }
+
+ /*
+ * Clear sme_cli before calling unifi_sys_... so it doesn't try to
+ * queue a reply to the (now gone) SME.
+ */
+ down(&udi_mutex);
+ priv->sme_cli = NULL;
+ up(&udi_mutex);
+#endif
+
+#ifdef CSR_SME_USERSPACE
+ /* Power-down when config client closes */
+ unifi_sys_wifi_off_req(priv);
+#endif /* CSR_SME_USERSPACE */
+ } else {
+
+ /* If the pointer matches the logging client, stop logging. */
+ down(&priv->udi_logging_mutex);
+ if (udi_cli == priv->logging_client) {
+ priv->logging_client = NULL;
+ }
+ up(&priv->udi_logging_mutex);
+
+ if (udi_cli == priv->amp_client) {
+ priv->amp_client = NULL;
+ }
+ }
+
+ /* Deregister this instance from the client's list. */
+ ul_deregister_client(udi_cli);
+
+
+ devno = MINOR(inode->i_rdev) >> 1;
+ unifi_put_instance(devno);
+
+ return 0;
+} /* unifi_release() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read
+ *
+ * The read() driver entry point.
+ *
+ * Arguments:
+ * filp The file descriptor returned by unifi_open()
+ * p The user space buffer to copy the read data
+ * len The size of the p buffer
+ * poff
+ *
+ * Returns:
+ * number of bytes read or an error code on failure
+ * ---------------------------------------------------------------------------
+ */
+static ssize_t
+unifi_read(struct file *filp, char *p, size_t len, loff_t *poff)
+{
+ ul_client_t *pcli = (void*)filp->private_data;
+ unifi_priv_t *priv;
+ udi_log_t *logptr = NULL;
+ udi_msg_t *msgptr;
+ struct list_head *l;
+ int msglen;
+
+ func_enter();
+
+ priv = unifi_find_instance(pcli->instance);
+ if (!priv) {
+ unifi_error(priv, "invalid priv\n");
+ return -ENODEV;
+ }
+
+ if (!pcli->udi_enabled) {
+ unifi_error(priv, "unifi_read: unknown client.");
+ return -EINVAL;
+ }
+
+ if (list_empty(&pcli->udi_log)) {
+ if (filp->f_flags & O_NONBLOCK) {
+ /* Non-blocking - just return if the udi_log is empty */
+ return 0;
+ } else {
+ /* Blocking - wait on the UDI wait queue */
+ if (wait_event_interruptible(pcli->udi_wq,
+ !list_empty(&pcli->udi_log)))
+ {
+ unifi_error(priv, "unifi_read: wait_event_interruptible failed.");
+ return -ERESTARTSYS;
+ }
+ }
+ }
+
+ /* Read entry from list head and remove it from the list */
+ if (down_interruptible(&pcli->udi_sem)) {
+ return -ERESTARTSYS;
+ }
+ l = pcli->udi_log.next;
+ list_del(l);
+ up(&pcli->udi_sem);
+
+ /* Get a pointer to whole struct */
+ logptr = list_entry(l, udi_log_t, q);
+ if (logptr == NULL) {
+ unifi_error(priv, "unifi_read: failed to get event.\n");
+ return -EINVAL;
+ }
+
+ /* Get the real message */
+ msgptr = &logptr->msg;
+ msglen = msgptr->length;
+ if (msglen > len) {
+ printk(KERN_WARNING "truncated read to %d actual msg len is %d\n", msglen, len);
+ msglen = len;
+ }
+
+ /* and pass it to the client (SME or Unicli). */
+ if (copy_to_user(p, msgptr, msglen))
+ {
+ printk(KERN_ERR "Failed to copy UDI log to user\n");
+ kfree(logptr);
+ return -EFAULT;
+ }
+
+ /* It is our resposibility to free the message buffer. */
+ kfree(logptr);
+
+ func_exit_r(msglen);
+ return msglen;
+
+} /* unifi_read() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * udi_send_signal_unpacked
+ *
+ * Sends an unpacked signal to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to private context struct
+ * data Pointer to request structure and data to send
+ * data_len Length of data in data pointer.
+ *
+ * Returns:
+ * Number of bytes written, error otherwise.
+ *
+ * Notes:
+ * All clients that use this function to send a signal to the unifi
+ * must use the host formatted structures.
+ * ---------------------------------------------------------------------------
+ */
+static int
+udi_send_signal_unpacked(unifi_priv_t *priv, unsigned char* data, uint data_len)
+{
+ CSR_SIGNAL *sigptr = (CSR_SIGNAL*)data;
+ CSR_DATAREF *datarefptr;
+ bulk_data_param_t bulk_data;
+ uint signal_size, i;
+ uint bulk_data_offset = 0;
+ int bytecount, r;
+
+ /* Number of bytes in the signal */
+ signal_size = SigGetSize(sigptr);
+ if (!signal_size || (signal_size > data_len)) {
+ unifi_error(priv, "unifi_sme_mlme_req - Invalid signal 0x%x size should be %d bytes\n",
+ sigptr->SignalPrimitiveHeader.SignalId,
+ signal_size);
+ return -EINVAL;
+ }
+ bytecount = signal_size;
+
+ /* Get a pointer to the information of the first data reference */
+ datarefptr = (CSR_DATAREF*)&sigptr->u;
+
+ /* Initialize the offset in the data buffer, bulk data is right after the signal. */
+ bulk_data_offset = signal_size;
+
+ /* store the references and the size of the bulk data to the bulkdata structure */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ /* the length of the bulk data is in the signal */
+ if ((datarefptr+i)->DataLength) {
+ void *dest;
+
+ r = unifi_net_data_malloc(priv, &bulk_data.d[i], (datarefptr+i)->DataLength);
+ if (r != 0) {
+ unifi_error(priv, "udi_send_signal_unpacked: failed to allocate request_data.\n");
+ return -EIO;
+ }
+
+ dest = (void*)bulk_data.d[i].os_data_ptr;
+ memcpy(dest, data + bulk_data_offset, bulk_data.d[i].data_length);
+ } else {
+ bulk_data.d[i].data_length = 0;
+ }
+
+ bytecount += bulk_data.d[i].data_length;
+ /* advance the offset, to point the next bulk data */
+ bulk_data_offset += bulk_data.d[i].data_length;
+ }
+
+
+ unifi_trace(priv, UDBG3, "SME Send: signal %s\n",
+ lookup_signal_name(sigptr->SignalPrimitiveHeader.SignalId));
+
+ /* Send the signal. */
+ r = ul_send_signal_unpacked(priv, sigptr, &bulk_data);
+ if (r < 0) {
+ unifi_error(priv, "udi_send_signal_unpacked: send failed (%d)\n", r);
+ func_exit();
+ return -EIO;
+ }
+
+ return bytecount;
+} /* udi_send_signal_unpacked() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * udi_send_signal_raw
+ *
+ * Sends a packed signal to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to private context struct
+ * buf Pointer to request structure and data to send
+ * buflen Length of data in data pointer.
+ *
+ * Returns:
+ * Number of bytes written, error otherwise.
+ *
+ * Notes:
+ * All clients that use this function to send a signal to the unifi
+ * must use the wire formatted structures.
+ * ---------------------------------------------------------------------------
+ */
+static int
+udi_send_signal_raw(unifi_priv_t *priv, const unsigned char *buf, int buflen)
+{
+ int signal_size;
+ int sig_id;
+ bulk_data_param_t data_ptrs;
+ int i, r;
+ unsigned int num_data_refs;
+ int bytecount;
+
+ func_enter();
+
+ /*
+ * The signal is the first thing in buf, the signal id is the
+ * first 16 bits of the signal, so we can just pass the buffer to
+ * get_packed_struct_size() as if it were a CSR_SIGNAL.
+ */
+ /* Number of bytes in the signal */
+ sig_id = GET_SIGNAL_ID(buf);
+ signal_size = get_packed_struct_size(buf);
+ if (signal_size <= 0) {
+ unifi_error(priv, "udi_send_signal_raw - Couldn't find length of signal 0x%x\n",
+ sig_id);
+ func_exit();
+ return -EINVAL;
+ }
+
+ unifi_trace(priv, UDBG2, "udi_send_signal_raw: signal %s len:%d\n",
+ lookup_signal_name(sig_id), signal_size);
+ /* Zero the data ref arrays */
+ memset(&data_ptrs, 0, sizeof(data_ptrs));
+
+ /*
+ * Find the number of associated bulk data packets. Scan through
+ * the data refs to check that we have enough data and pick out
+ * pointers to appended bulk data.
+ */
+ num_data_refs = 0;
+ bytecount = signal_size;
+
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i)
+ {
+ unsigned int len = GET_PACKED_DATAREF_LEN(buf, i);
+ unifi_trace(priv, UDBG3, "udi_send_signal_raw: data_ref length = %d\n", len);
+
+ if (len != 0) {
+ void *dest;
+
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[i], len);
+ if (r != 0) {
+ unifi_error(priv, "udi_send_signal_raw: failed to allocate request_data.\n");
+ return -EIO;
+ }
+
+ dest = (void*)data_ptrs.d[i].os_data_ptr;
+ memcpy(dest, buf + bytecount, len);
+
+ bytecount += len;
+ num_data_refs++;
+ }
+ data_ptrs.d[i].data_length = len;
+ }
+
+ unifi_trace(priv, UDBG3, "Queueing signal 0x%X %s from UDI with %u data refs\n",
+ sig_id,
+ lookup_signal_name(sig_id),
+ num_data_refs);
+
+ if (bytecount > buflen) {
+ unifi_error(priv, "udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen, bytecount);
+ func_exit();
+ return -EINVAL;
+ }
+
+ /* Send the signal calling the function that uses the wire-formatted signals. */
+ r = ul_send_signal_raw(priv, buf, signal_size, &data_ptrs);
+ if (r < 0) {
+ unifi_error(priv, "udi_send_signal_raw: send failed (%d)\n", r);
+ func_exit();
+ return -EIO;
+ }
+
+#ifdef CSR_NATIVE_LINUX
+ if (sig_id == CSR_MLME_POWERMGT_REQUEST_ID) {
+ /* Overide the wext power mode to the new value */
+ priv->wext_conf.power_mode = UNPACK16((buf),
+ SIZEOF_SIGNAL_HEADER + (UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF));
+
+ /* Configure deep sleep signaling */
+ if (priv->wext_conf.power_mode || (priv->connected == UnifiNotConnected)) {
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_ENABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+ } else {
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_DISABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+ }
+ }
+#endif
+
+ func_exit_r(bytecount);
+
+ return bytecount;
+} /* udi_send_signal_raw */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_write
+ *
+ * The write() driver entry point.
+ * A UniFi Debug Interface client such as unicli can write a signal
+ * plus bulk data to the driver for sending to the UniFi chip.
+ *
+ * Only one signal may be sent per write operation.
+ *
+ * Arguments:
+ * filp The file descriptor returned by unifi_open()
+ * p The user space buffer to get the data from
+ * len The size of the p buffer
+ * poff
+ *
+ * Returns:
+ * number of bytes written or an error code on failure
+ * ---------------------------------------------------------------------------
+ */
+static ssize_t
+unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
+{
+ ul_client_t *pcli = (ul_client_t*)filp->private_data;
+ unifi_priv_t *priv;
+ unsigned char *buf;
+ unsigned char *bufptr;
+ int remaining;
+ int bytes_written;
+ int r;
+ bulk_data_param_t bulkdata;
+
+ func_enter();
+
+ priv = unifi_find_instance(pcli->instance);
+ if (!priv) {
+ unifi_error(priv, "invalid priv\n");
+ return -ENODEV;
+ }
+
+ unifi_trace(priv, UDBG5, "unifi_write: len = %d\n", len);
+
+ if (!pcli->udi_enabled) {
+ unifi_error(priv, "udi disabled\n");
+ return -EINVAL;
+ }
+
+ /*
+ * AMP client sends only one signal at a time, so we can use
+ * unifi_net_data_malloc to save the extra copy.
+ */
+ if (pcli == priv->amp_client) {
+ int signal_size;
+ int sig_id;
+ unsigned char *signal_buf;
+
+ r = unifi_net_data_malloc(priv, &bulkdata.d[0], len);
+ if (r) {
+ unifi_error(priv, "unifi_write: failed to allocate request_data.\n");
+ func_exit();
+ return -ENOMEM;
+ }
+
+ /* Get the data from the AMP client. */
+ if (copy_from_user((char*)bulkdata.d[0].os_data_ptr, p, len)) {
+ unifi_error(priv, "unifi_write: copy from user failed\n");
+ unifi_net_data_free(priv, &bulkdata.d[0]);
+ func_exit();
+ return -EFAULT;
+ }
+
+ bulkdata.d[1].data_length = 0;
+
+ /* Number of bytes in the signal */
+ sig_id = GET_SIGNAL_ID(bulkdata.d[0].os_data_ptr);
+ signal_size = get_packed_struct_size(bulkdata.d[0].os_data_ptr);
+ if ((signal_size <= 0) || (signal_size > len)) {
+ unifi_error(priv, "unifi_write - Couldn't find length of signal 0x%x\n",
+ sig_id);
+ unifi_net_data_free(priv, &bulkdata.d[0]);
+ func_exit();
+ return -EINVAL;
+ }
+
+ unifi_trace(priv, UDBG2, "unifi_write: signal %s len:%d\n",
+ lookup_signal_name(sig_id), signal_size);
+
+ /* Allocate a buffer for the signal */
+ signal_buf = kmalloc(signal_size, GFP_KERNEL);
+ if (!signal_buf) {
+ unifi_net_data_free(priv, &bulkdata.d[0]);
+ func_exit();
+ return -ENOMEM;
+ }
+
+ /* Get the signal from the os_data_ptr */
+ memcpy(signal_buf, bulkdata.d[0].os_data_ptr, signal_size);
+ signal_buf[5] = (pcli->sender_id >> 8) & 0xff;
+
+ if (signal_size < len) {
+ /* Remove the signal from the os_data_ptr */
+ bulkdata.d[0].data_length -= signal_size;
+ bulkdata.d[0].os_data_ptr += signal_size;
+ } else {
+ bulkdata.d[0].data_length = 0;
+ bulkdata.d[0].os_data_ptr = NULL;
+ }
+
+ /* Send the signal calling the function that uses the wire-formatted signals. */
+ r = ul_send_signal_raw(priv, signal_buf, signal_size, &bulkdata);
+ if (r < 0) {
+ unifi_error(priv, "unifi_write: send failed (%d)\n", r);
+ if (bulkdata.d[0].os_data_ptr != NULL) {
+ unifi_net_data_free(priv, &bulkdata.d[0]);
+ }
+ }
+
+ /* Free the signal buffer and return */
+ kfree(signal_buf);
+ return len;
+ }
+
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf) {
+ return -ENOMEM;
+ }
+
+ /* Get the data from the client (SME or Unicli). */
+ if (copy_from_user(buf, p, len)) {
+ unifi_error(priv, "copy from user failed\n");
+ kfree(buf);
+ return -EFAULT;
+ }
+
+ /*
+ * In SME userspace build read() contains a SYS or MGT message.
+ * Note that even though the SME sends one signal at a time, we can not
+ * use unifi_net_data_malloc because in the early stages, before having
+ * initialised the core, it will fail since the I/O block size is unknown.
+ */
+#ifdef CSR_SME_USERSPACE
+ if (pcli->configuration & CLI_SME_USERSPACE) {
+ /*
+ * Should change this to check for HIP signal id and fall-through
+ * if it's a HIP signal.
+ */
+ r = receive_remote_sys_hip_req(priv->smepriv, buf, len); /* Hip Messages */
+ if (!r) {
+ r = remote_sys_signal_receive(priv->smepriv, buf, len);
+ if (!r) {
+ r = remote_mgt_signal_receive(priv->smepriv, buf, len);
+ if (!r) {
+ unifi_error(priv, "SME can not process the message\n");
+ /* FIXME: For debug only, remove it later */
+ dump(buf, len);
+ }
+ }
+ }
+
+ kfree(buf);
+ return len;
+ }
+#endif
+
+ /* ul_send_signal_raw will do a sanity check of len against signal content */
+
+ /*
+ * udi_send_signal_raw() and udi_send_signal_unpacked() return the number of bytes consumed.
+ * A write call can pass multiple signal concatenated together.
+ */
+ bytes_written = 0;
+ remaining = len;
+ bufptr = buf;
+ while (remaining > 0)
+ {
+ int r;
+
+ /*
+ * Set the SenderProcessId.
+ * The SignalPrimitiveHeader is the first 3 16-bit words of the signal,
+ * the SenderProcessId is bytes 4,5.
+ * The MSB of the sender ID needs to be set to the client ID.
+ * The LSB is controlled by the SME.
+ */
+ bufptr[5] = (pcli->sender_id >> 8) & 0xff;
+
+ /* use the appropriate interface, depending on the clients' configuration */
+ if (pcli->configuration & CLI_USING_WIRE_FORMAT) {
+ unifi_trace(priv, UDBG1, "unifi_write: call udi_send_signal().\n");
+ r = udi_send_signal_raw(priv, bufptr, remaining);
+ } else {
+ r = udi_send_signal_unpacked(priv, bufptr, remaining);
+ }
+ if (r < 0) {
+ /* Set the return value to the error code */
+ unifi_error(priv, "unifi_write: (udi or sme)_send_signal() returns %d\n", r);
+ bytes_written = r;
+ break;
+ }
+ bufptr += r;
+ remaining -= r;
+ bytes_written += r;
+ }
+
+ kfree(buf);
+
+ func_exit_r(bytes_written);
+
+ return bytes_written;
+} /* unifi_write() */
+
+
+
+
+
+/*
+ * ----------------------------------------------------------------
+ * unifi_ioctl
+ *
+ * Ioctl handler for unifi driver.
+ *
+ * Arguments:
+ * inodep Pointer to inode structure.
+ * filp Pointer to file structure.
+ * cmd Ioctl cmd passed by user.
+ * arg Ioctl arg passed by user.
+ *
+ * Returns:
+ * 0 on success, -ve error code on error.
+ * ----------------------------------------------------------------
+ */
+static int
+unifi_ioctl(struct inode *inodep, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ ul_client_t *pcli = (ul_client_t*)filp->private_data;
+ unifi_priv_t *priv;
+ struct net_device *dev;
+ int rc = 0;
+ int int_param, i;
+ u8* buf;
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ unifi_cfg_command_t cfg_cmd;
+ unifi_CoexConfig coex_config;
+ unifi_AppValue sme_app_value;
+ unsigned char uchar_param;
+ unsigned char varbind[MAX_VARBIND_LENGTH];
+ int vblen;
+#endif
+ unifi_putest_command_t putest_cmd;
+
+ priv = unifi_find_instance(pcli->instance);
+ if (!priv) {
+ unifi_error(priv, "ioctl error: unknown instance=%d\n", pcli->instance);
+ return -ENODEV;
+ }
+ unifi_trace(priv, UDBG5, "unifi_ioctl: cmd=0x%X, arg=0x%lX\n", cmd, arg);
+
+ dev = priv->netdev;
+
+ switch (cmd) {
+
+ case UNIFI_GET_UDI_ENABLE:
+ unifi_trace(priv, UDBG4, "UniFi Get UDI Enable\n");
+
+ down(&priv->udi_logging_mutex);
+ int_param = (priv->logging_client == NULL) ? 0 : 1;
+ up(&priv->udi_logging_mutex);
+
+ if (put_user(int_param, (int*)arg))
+ {
+ unifi_error(priv, "UNIFI_GET_UDI_ENABLE: Failed to copy to user\n");
+ return -EFAULT;
+ }
+ break;
+
+ case UNIFI_SET_UDI_ENABLE:
+ unifi_trace(priv, UDBG4, "UniFi Set UDI Enable\n");
+ if (get_user(int_param, (int*)arg))
+ {
+ unifi_error(priv, "UNIFI_SET_UDI_ENABLE: Failed to copy from user\n");
+ return -EFAULT;
+ }
+
+ down(&priv->udi_logging_mutex);
+ if (int_param) {
+ pcli->event_hook = udi_log_event;
+ unifi_set_udi_hook(priv->card, logging_handler);
+ /* Log all signals by default */
+ for (i = 0; i < SIG_FILTER_SIZE; i++) {
+ pcli->signal_filter[i] = 0xFFFF;
+ }
+ priv->logging_client = pcli;
+
+ } else {
+ priv->logging_client = NULL;
+ pcli->event_hook = NULL;
+ }
+ up(&priv->udi_logging_mutex);
+
+ break;
+
+ case UNIFI_SET_MIB:
+ unifi_trace(priv, UDBG4, "UniFi Set MIB\n");
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ /* Read first 2 bytes and check length */
+ if (copy_from_user(varbind, (void*)arg, 2)) {
+ unifi_error(priv,
+ "UNIFI_SET_MIB: Failed to copy in varbind header\n");
+ return -EFAULT;
+ }
+ vblen = varbind[1];
+ if ((vblen + 2) > MAX_VARBIND_LENGTH) {
+ unifi_error(priv,
+ "UNIFI_SET_MIB: Varbind too long (%d, limit %d)\n",
+ (vblen+2), MAX_VARBIND_LENGTH);
+ return -EINVAL;
+ }
+ /* Read rest of varbind */
+ if (copy_from_user(varbind+2, (void*)(arg+2), vblen)) {
+ unifi_error(priv, "UNIFI_SET_MIB: Failed to copy in varbind\n");
+ return -EFAULT;
+ }
+
+ /* send to SME */
+ vblen += 2;
+ rc = sme_mgt_mib_set(priv, varbind, vblen);
+ if (rc) {
+ return rc;
+ }
+#else
+ unifi_notice(priv, "UNIFI_SET_MIB: Unsupported.\n");
+#endif /* CSR_SUPPORT_WEXT */
+ break;
+
+ case UNIFI_GET_MIB:
+ unifi_trace(priv, UDBG4, "UniFi Get MIB\n");
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ /* Read first 2 bytes and check length */
+ if (copy_from_user(varbind, (void*)arg, 2)) {
+ unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind header\n");
+ return -EFAULT;
+ }
+ vblen = varbind[1];
+ if ((vblen+2) > MAX_VARBIND_LENGTH) {
+ unifi_error(priv, "UNIFI_GET_MIB: Varbind too long (%d, limit %d)\n",
+ (vblen+2), MAX_VARBIND_LENGTH);
+ return -EINVAL;
+ }
+ /* Read rest of varbind */
+ if (copy_from_user(varbind+2, (void*)(arg+2), vblen)) {
+ unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind\n");
+ return -EFAULT;
+ }
+
+ vblen += 2;
+ rc = sme_mgt_mib_get(priv, varbind, &vblen);
+ if (rc) {
+ return rc;
+ }
+ /* copy out varbind */
+ if (vblen > MAX_VARBIND_LENGTH) {
+ unifi_error(priv,
+ "UNIFI_GET_MIB: Varbind result too long (%d, limit %d)\n",
+ vblen, MAX_VARBIND_LENGTH);
+ return -EINVAL;
+ }
+ if (copy_to_user((void*)arg, varbind, vblen)) {
+ return -EFAULT;
+ }
+#else
+ unifi_notice(priv, "UNIFI_GET_MIB: Unsupported.\n");
+#endif /* CSR_SUPPORT_WEXT */
+ break;
+
+ case UNIFI_CFG:
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ if (get_user(cfg_cmd, (unifi_cfg_command_t*)arg))
+ {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the command\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG2, "UNIFI_CFG: Command is %d\n", cfg_cmd);
+ switch (cfg_cmd) {
+ case UNIFI_CFG_POWER:
+ rc = unifi_cfg_power(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_CFG_POWERSAVE:
+ rc = unifi_cfg_power_save(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_CFG_POWERSUPPLY:
+ rc = unifi_cfg_power_supply(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_CFG_FILTER:
+ rc = unifi_cfg_packet_filters(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_CFG_GET:
+ rc = unifi_cfg_get_info(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_CFG_WMM_QOSINFO:
+ rc = unifi_cfg_wmm_qos_info(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_CFG_WMM_ADDTS:
+ rc = unifi_cfg_wmm_addts(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_CFG_WMM_DELTS:
+ rc = unifi_cfg_wmm_delts(priv, (unsigned char*)arg);
+ break;
+ default:
+ unifi_error(priv, "UNIFI_CFG: Unknown Command (%d)\n", cfg_cmd);
+ return -EINVAL;
+ }
+#endif
+
+ break;
+
+ case UNIFI_PUTEST:
+ if (get_user(putest_cmd, (unifi_putest_command_t*)arg))
+ {
+ unifi_error(priv, "UNIFI_PUTEST: Failed to get the command\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG2, "UNIFI_PUTEST: Command is %s\n",
+ trace_putest_cmdid(putest_cmd));
+ switch (putest_cmd) {
+ case UNIFI_PUTEST_START:
+ rc = unifi_putest_start(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_PUTEST_STOP:
+ rc = unifi_putest_stop(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_PUTEST_SET_SDIO_CLOCK:
+ rc = unifi_putest_set_sdio_clock(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_PUTEST_CMD52_READ:
+ rc = unifi_putest_cmd52_read(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_PUTEST_CMD52_WRITE:
+ rc = unifi_putest_cmd52_write(priv, (unsigned char*)arg);
+ break;
+ case UNIFI_PUTEST_DL_FW:
+ rc = unifi_putest_dl_fw(priv, (unsigned char*)arg);
+ break;
+ default:
+ unifi_error(priv, "UNIFI_PUTEST: Unknown Command (%d)\n", putest_cmd);
+ return -EINVAL;
+ }
+
+ break;
+
+ case UNIFI_INIT_HW:
+ unifi_trace(priv, UDBG2, "UNIFI_INIT_HW.\n");
+ priv->init_progress = UNIFI_INIT_NONE;
+
+#ifdef CSR_SUPPORT_WEXT
+ /* At this point we are ready to start the SME. */
+ rc = sme_mgt_wifi_on(priv);
+ if (rc) {
+ return rc;
+ }
+#endif
+
+ break;
+
+ case UNIFI_INIT_NETDEV:
+ unifi_trace(priv, UDBG2, "UNIFI_INIT_NETDEV.\n");
+ if (copy_from_user(dev->dev_addr, (void*)arg, 6)) {
+ return -EFAULT;
+ }
+
+ /* Attach the network device to the stack */
+ if (!priv->netdev_registered)
+ {
+ rc = uf_register_netdev(priv);
+ if (rc) {
+ unifi_error(priv, "Failed to register the network device.\n");
+ return rc;
+ }
+ }
+
+ priv->init_progress = UNIFI_INIT_COMPLETED;
+
+ unifi_info(priv, "UniFi ready\n");
+ break;
+
+ case UNIFI_GET_INIT_STATUS:
+ unifi_trace(priv, UDBG2, "UNIFI_GET_INIT_STATUS.\n");
+ if (put_user(priv->init_progress, (int*)arg))
+ {
+ printk(KERN_ERR "UNIFI_GET_INIT_STATUS: Failed to copy to user\n");
+ return -EFAULT;
+ }
+ break;
+
+ case UNIFI_KICK:
+ unifi_trace(priv, UDBG4, "Kick UniFi\n");
+ unifi_sdio_interrupt_handler(priv->card);
+ break;
+
+ case UNIFI_SET_DEBUG:
+ unifi_debug = arg;
+ unifi_trace(priv, UDBG4, "unifi_debug set to %d\n", unifi_debug);
+ break;
+
+ case UNIFI_SET_TRACE:
+ /* no longer supported */
+ rc = -EINVAL;
+ break;
+
+ case UNIFI_SET_UDI_LOG_MASK:
+ {
+ unifiio_filter_t udi_filter;
+ uint16_t *sig_ids_addr;
+#define UF_MAX_SIG_IDS 128 /* Impose a sensible limit */
+
+ if (copy_from_user(&udi_filter, (void*)arg, sizeof(udi_filter))) {
+ return -EFAULT;
+ }
+ if ((udi_filter.action < UfSigFil_AllOn) ||
+ (udi_filter.action > UfSigFil_SelectOff))
+ {
+ printk(KERN_WARNING
+ "UNIFI_SET_UDI_LOG_MASK: Bad action value: %d\n",
+ udi_filter.action);
+ return -EINVAL;
+ }
+ /* No signal list for "All" actions */
+ if ((udi_filter.action == UfSigFil_AllOn) ||
+ (udi_filter.action == UfSigFil_AllOff))
+ {
+ udi_filter.num_sig_ids = 0;
+ }
+
+ if (udi_filter.num_sig_ids > UF_MAX_SIG_IDS) {
+ printk(KERN_WARNING
+ "UNIFI_SET_UDI_LOG_MASK: too many signal ids (%d, max %d)\n",
+ udi_filter.num_sig_ids, UF_MAX_SIG_IDS);
+ return -EINVAL;
+ }
+
+ /* Copy in signal id list if given */
+ if (udi_filter.num_sig_ids > 0) {
+ /* Preserve userspace address of sig_ids array */
+ sig_ids_addr = udi_filter.sig_ids;
+ /* Allocate kernel memory for sig_ids and copy to it */
+ udi_filter.sig_ids =
+ kmalloc(udi_filter.num_sig_ids * sizeof(uint16_t), GFP_KERNEL);
+ if (!udi_filter.sig_ids) {
+ return -ENOMEM;
+ }
+ if (copy_from_user(udi_filter.sig_ids,
+ (void*)sig_ids_addr,
+ udi_filter.num_sig_ids * sizeof(uint16_t)))
+ {
+ kfree(udi_filter.sig_ids);
+ return -EFAULT;
+ }
+ }
+
+ udi_set_log_filter(pcli, &udi_filter);
+
+ if (udi_filter.num_sig_ids > 0) {
+ kfree(udi_filter.sig_ids);
+ }
+ }
+ break;
+
+ case UNIFI_SET_AMP_ENABLE:
+ unifi_trace(priv, UDBG4, "UniFi Set AMP Enable\n");
+ if (get_user(int_param, (int*)arg))
+ {
+ unifi_error(priv, "UNIFI_SET_AMP_ENABLE: Failed to copy from user\n");
+ return -EFAULT;
+ }
+
+ if (int_param) {
+ priv->amp_client = pcli;
+ } else {
+ priv->amp_client = NULL;
+ }
+
+ int_param = 0;
+ buf = (u8*)&int_param;
+ buf[0] = UNIFI_SOFT_COMMAND_Q_LENGTH - 1;
+ buf[1] = UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1;
+ if (copy_to_user((void*)arg, &int_param, sizeof(int))) {
+ return -EFAULT;
+ }
+ break;
+
+ case UNIFI_SET_UDI_SNAP_MASK:
+ {
+ unifiio_snap_filter_t snap_filter;
+
+ if (copy_from_user(&snap_filter, (void*)arg, sizeof(snap_filter))) {
+ return -EFAULT;
+ }
+
+ if (pcli->snap_filter.count) {
+ pcli->snap_filter.count = 0;
+ unifi_free(priv, pcli->snap_filter.protocols);
+ }
+
+ if (snap_filter.count == 0) {
+ break;
+ }
+
+ pcli->snap_filter.protocols = unifi_malloc(priv,
+ snap_filter.count * sizeof(uint16));
+ if (!pcli->snap_filter.protocols) {
+ return -ENOMEM;
+ }
+ if (copy_from_user(pcli->snap_filter.protocols,
+ (void*)snap_filter.protocols,
+ snap_filter.count * sizeof(uint16)))
+ {
+ unifi_free(priv, pcli->snap_filter.protocols);
+ return -EFAULT;
+ }
+
+ pcli->snap_filter.count = snap_filter.count;
+
+ }
+ break;
+
+ case UNIFI_SME_PRESENT:
+ {
+ u8 ind;
+ unifi_trace(priv, UDBG4, "UniFi SME Present IOCTL.\n");
+ if (copy_from_user(&int_param, (void*)arg, sizeof(int)))
+ {
+ printk(KERN_ERR "UNIFI_SME_PRESENT: Failed to copy from user\n");
+ return -EFAULT;
+ }
+
+ priv->sme_is_present = int_param;
+ if (priv->sme_is_present == 1) {
+ ind = CONFIG_SME_PRESENT;
+ } else {
+ ind = CONFIG_SME_NOT_PRESENT;
+ }
+ /* Send an indication to the helper app. */
+ ul_log_config_ind(priv, &ind, sizeof(u8));
+ }
+ break;
+
+ case UNIFI_CFG_PERIOD_TRAFFIC:
+ unifi_trace(priv, UDBG4, "UniFi Configure Periodic Traffic.\n");
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ if (copy_from_user(&uchar_param, (void*)arg, sizeof(unsigned char))) {
+ unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
+ return -EFAULT;
+ }
+
+ if (uchar_param == 0) {
+ sme_app_value.id = unifi_CoexConfigValue;
+ rc = sme_mgt_get_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Get unifi_CoexInfoValue failed.\n");
+ return rc;
+ }
+ if (copy_to_user((void*)(arg + 1),
+ (void*)&sme_app_value.unifi_Value_union.coexConfig,
+ sizeof(unifi_CoexConfig))) {
+ return -EFAULT;
+ }
+ return 0;
+ }
+
+ if (copy_from_user(&coex_config, (void*)(arg + 1), sizeof(unifi_CoexConfig)))
+ {
+ unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
+ return -EFAULT;
+ }
+
+ sme_app_value.unifi_Value_union.coexConfig = coex_config;
+ sme_app_value.id = unifi_CoexConfigValue;
+ rc = sme_mgt_set_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Set unifi_CoexInfoValue failed.\n");
+ return rc;
+ }
+
+#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
+ break;
+
+ case UNIFI_CFG_UAPSD_TRAFFIC:
+ unifi_trace(priv, UDBG4, "UniFi Configure U-APSD Mask.\n");
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ if (copy_from_user(&uchar_param, (void*)arg, sizeof(unsigned char))) {
+ unifi_error(priv, "UNIFI_CFG_UAPSD_TRAFFIC: Failed to copy from user\n");
+ return -EFAULT;
+ }
+ unifi_trace(priv, UDBG4, "New U-APSD Mask: 0x%x\n", uchar_param);
+#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
+ break;
+
+ default:
+ rc = -EINVAL;
+ }
+
+ return rc;
+} /* unifi_ioctl() */
+
+
+
+static unsigned int
+unifi_poll(struct file *filp, poll_table *wait)
+{
+ ul_client_t *pcli = (ul_client_t*)filp->private_data;
+ unsigned int mask = 0;
+ int ready;
+
+ func_enter();
+
+ ready = !list_empty(&pcli->udi_log);
+
+ poll_wait(filp, &pcli->udi_wq, wait);
+
+ if (ready) {
+ mask |= POLLIN | POLLRDNORM; /* readable */
+ }
+
+ func_exit();
+
+ return mask;
+} /* unifi_poll() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * udi_set_log_filter
+ *
+ * Configure the bit mask that determines which signal primitives are
+ * passed to the logging process.
+ *
+ * Arguments:
+ * pcli Pointer to the client to configure.
+ * udi_filter Pointer to a unifiio_filter_t containing instructions.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * SigGetFilterPos() returns a 32-bit value that contains an index and a
+ * mask for accessing a signal_filter array. The top 16 bits specify an
+ * index into a signal_filter, the bottom 16 bits specify a mask to
+ * apply.
+ * ---------------------------------------------------------------------------
+ */
+static void
+udi_set_log_filter(ul_client_t *pcli, unifiio_filter_t *udi_filter)
+{
+ uint32 filter_pos;
+ int i;
+
+ if (udi_filter->action == UfSigFil_AllOn)
+ {
+ for (i = 0; i < SIG_FILTER_SIZE; i++) {
+ pcli->signal_filter[i] = 0xFFFF;
+ }
+ }
+ else if (udi_filter->action == UfSigFil_AllOff)
+ {
+ for (i = 0; i < SIG_FILTER_SIZE; i++) {
+ pcli->signal_filter[i] = 0;
+ }
+ }
+ else if (udi_filter->action == UfSigFil_SelectOn)
+ {
+ for (i = 0; i < udi_filter->num_sig_ids; i++) {
+ filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]);
+ if (filter_pos == 0xFFFFFFFF)
+ {
+ printk(KERN_WARNING
+ "Unrecognised signal id (0x%X) specifed in logging filter\n",
+ udi_filter->sig_ids[i]);
+ } else {
+ pcli->signal_filter[filter_pos >> 16] |= (filter_pos & 0xFFFF);
+ }
+ }
+ }
+ else if (udi_filter->action == UfSigFil_SelectOff)
+ {
+ for (i = 0; i < udi_filter->num_sig_ids; i++) {
+ filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]);
+ if (filter_pos == 0xFFFFFFFF)
+ {
+ printk(KERN_WARNING
+ "Unrecognised signal id (0x%X) specifed in logging filter\n",
+ udi_filter->sig_ids[i]);
+ } else {
+ pcli->signal_filter[filter_pos >> 16] &= ~(filter_pos & 0xFFFF);
+ }
+ }
+ }
+
+} /* udi_set_log_filter() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * udi_log_event
+ *
+ * Callback function to be registered as the UDI hook callback.
+ * Copies the signal content into a new udi_log_t struct and adds
+ * it to the read queue for this UDI client.
+ *
+ * Arguments:
+ * arg This is the value given to unifi_add_udi_hook, in
+ * this case a pointer to the client instance.
+ * s Pointer to the received signal.
+ * signal_len Size of the signal structure in bytes.
+ * data_ptrs Pointers to any associated bulk data.
+ * dir Direction of the signal. Zero means from host,
+ * non-zero means to host.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+udi_log_event(ul_client_t *pcli,
+ u8 *signal, int signal_len,
+ const bulk_data_param_t *bulkdata,
+ int dir)
+{
+ udi_log_t *logptr;
+ u8 *p;
+ int i;
+ int total_len;
+ udi_msg_t *msgptr;
+ uint32 filter_pos;
+
+ func_enter();
+
+ /* Just a sanity check */
+ if ((signal == NULL) || (signal_len <= 0)) {
+ return;
+ }
+
+ /*
+ * Apply the logging filter - only report signals that have their
+ * bit set in the filter mask.
+ */
+ filter_pos = SigGetFilterPos(GET_SIGNAL_ID(signal));
+
+ if ((filter_pos != 0xFFFFFFFF) &&
+ ((pcli->signal_filter[filter_pos >> 16] & (filter_pos & 0xFFFF)) == 0))
+ {
+ /* Signal is not wanted by client */
+ return;
+ }
+
+ /* Calculate the buffer we need to store signal plus bulk data */
+ total_len = signal_len;
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ total_len += bulkdata->d[i].data_length;
+ }
+
+ /* Allocate log structure plus actual signal. */
+ logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL);
+
+ if (logptr == NULL) {
+ printk(KERN_ERR
+ "Failed to allocate %d bytes for a UDI log record\n",
+ sizeof(udi_log_t) + total_len);
+ return;
+ }
+
+ /* Fill in udi_log struct */
+ INIT_LIST_HEAD(&logptr->q);
+ msgptr = &logptr->msg;
+ msgptr->length = sizeof(udi_msg_t) + total_len;
+ msgptr->timestamp = jiffies_to_msecs(jiffies);
+ msgptr->direction = dir;
+ msgptr->signal_length = signal_len;
+
+ /* Copy signal and bulk data to the log */
+ p = (u8 *)(msgptr + 1);
+ memcpy(p, signal, signal_len);
+ p += signal_len;
+
+ /* Append any bulk data */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ int len = bulkdata->d[i].data_length;
+
+ /*
+ * Len here might not be the same as the length in the bulk data slot.
+ * The slot length will always be even, but len could be odd.
+ */
+ if (len > 0) {
+ if (bulkdata->d[i].os_data_ptr) {
+ memcpy(p, bulkdata->d[i].os_data_ptr, len);
+ } else {
+ memset(p, 0, len);
+ }
+ p += len;
+ }
+ }
+
+ /* Add to tail of log queue */
+ if (down_interruptible(&pcli->udi_sem)) {
+ printk(KERN_WARNING "udi_log_event_q: Failed to get udi sem\n");
+ kfree(logptr);
+ func_exit();
+ return;
+ }
+ list_add_tail(&logptr->q, &pcli->udi_log);
+ up(&pcli->udi_sem);
+
+ /* Wake any waiting user process */
+ wake_up_interruptible(&pcli->udi_wq);
+
+ func_exit();
+} /* udi_log_event() */
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
+ device_create(_class, _parent, _devno, _priv, _fmt, _args)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
+ device_create_drvdata(_class, _parent, _devno, _priv, _fmt, _args)
+#else
+#define UF_DEVICE_CREATE(_class, _parent, _devno, _priv, _fmt, _args) \
+ device_create(_class, _parent, _devno, _fmt, _args)
+#endif
+
+/*
+ ****************************************************************************
+ *
+ * Driver instantiation
+ *
+ ****************************************************************************
+ */
+static struct file_operations unifi_fops = {
+ .owner = THIS_MODULE,
+ .open = unifi_open,
+ .release = unifi_release,
+ .read = unifi_read,
+ .write = unifi_write,
+ .ioctl = unifi_ioctl,
+ .poll = unifi_poll,
+};
+
+static dev_t unifi_first_devno;
+static struct class *unifi_class;
+
+
+int uf_create_device_nodes(unifi_priv_t *priv, int bus_id)
+{
+ dev_t devno;
+ int r;
+
+ cdev_init(&priv->unifi_cdev, &unifi_fops);
+
+ /* cdev_init() should set the cdev owner, but it does not */
+ priv->unifi_cdev.owner = THIS_MODULE;
+
+ devno = MKDEV(MAJOR(unifi_first_devno),
+ MINOR(unifi_first_devno) + (bus_id * MAX_UNIFI_DEVS));
+ r = cdev_add(&priv->unifi_cdev, devno, 1);
+ if (r) {
+ return r;
+ }
+
+#ifdef SDIO_EXPORTS_STRUCT_DEVICE
+ if (!UF_DEVICE_CREATE(unifi_class, priv->unifi_device,
+ devno, priv, "unifi%d", bus_id)) {
+#else
+ priv->unifi_device = UF_DEVICE_CREATE(unifi_class, NULL,
+ devno, priv, "unifi%d", bus_id);
+ if (priv->unifi_device == NULL) {
+#endif /* SDIO_EXPORTS_STRUCT_DEVICE */
+
+ cdev_del(&priv->unifi_cdev);
+ return -EINVAL;
+ }
+
+ cdev_init(&priv->unifiudi_cdev, &unifi_fops);
+
+ /* cdev_init() should set the cdev owner, but it does not */
+ priv->unifiudi_cdev.owner = THIS_MODULE;
+
+ devno = MKDEV(MAJOR(unifi_first_devno),
+ MINOR(unifi_first_devno) + (bus_id * MAX_UNIFI_DEVS) + 1);
+ r = cdev_add(&priv->unifiudi_cdev, devno, 1);
+ if (r) {
+ device_destroy(unifi_class, priv->unifi_cdev.dev);
+ cdev_del(&priv->unifi_cdev);
+ return r;
+ }
+
+ if (!UF_DEVICE_CREATE(unifi_class,
+#ifdef SDIO_EXPORTS_STRUCT_DEVICE
+ priv->unifi_device,
+#else
+ NULL,
+#endif /* SDIO_EXPORTS_STRUCT_DEVICE */
+ devno, priv, "unifiudi%d", bus_id)) {
+ device_destroy(unifi_class, priv->unifi_cdev.dev);
+ cdev_del(&priv->unifiudi_cdev);
+ cdev_del(&priv->unifi_cdev);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+void uf_destroy_device_nodes(unifi_priv_t *priv)
+{
+ device_destroy(unifi_class, priv->unifiudi_cdev.dev);
+ device_destroy(unifi_class, priv->unifi_cdev.dev);
+ cdev_del(&priv->unifiudi_cdev);
+ cdev_del(&priv->unifi_cdev);
+}
+
+
+
+/*
+ * ----------------------------------------------------------------
+ * uf_create_debug_device
+ *
+ * Allocates device numbers for unifi character device nodes
+ * and creates a unifi class in sysfs
+ *
+ * Arguments:
+ * fops Pointer to the char device operations structure.
+ *
+ * Returns:
+ * 0 on success, -ve error code on error.
+ * ----------------------------------------------------------------
+ */
+static int
+uf_create_debug_device(struct file_operations *fops)
+{
+ int ret;
+
+ /* Allocate two device numbers for each device. */
+ ret = alloc_chrdev_region(&unifi_first_devno, 0, MAX_UNIFI_DEVS*2, UNIFI_NAME);
+ if (ret) {
+ unifi_error(NULL, "Failed to add alloc dev numbers: %d\n", ret);
+ return ret;
+ }
+
+ /* Create a UniFi class */
+ unifi_class = class_create(THIS_MODULE, UNIFI_NAME);
+ if (IS_ERR(unifi_class)) {
+ unifi_error(NULL, "Failed to create UniFi class\n");
+
+ /* Release device numbers */
+ unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2);
+ unifi_first_devno = 0;
+ return -EINVAL;
+ }
+
+ return 0;
+} /* uf_create_debug_device() */
+
+
+/*
+ * ----------------------------------------------------------------
+ * uf_remove_debug_device
+ *
+ * Destroys the unifi class and releases the allocated
+ * device numbers for unifi character device nodes.
+ *
+ * Arguments:
+ *
+ * Returns:
+ * ----------------------------------------------------------------
+ */
+static void
+uf_remove_debug_device(void)
+{
+ /* Destroy the UniFi class */
+ class_destroy(unifi_class);
+
+ /* Release device numbers */
+ unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2);
+ unifi_first_devno = 0;
+
+} /* uf_remove_debug_device() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Module loading.
+ *
+ * ---------------------------------------------------------------------------
+ */
+int __init
+unifi_load(void)
+{
+ int r;
+
+ printk("UniFi SDIO Driver: v%s (build:%d) %s %s\n",
+ UNIFI_DRIVER_VERSION,
+ UNIFI_DRIVER_BUILD_ID,
+ __DATE__, __TIME__);
+
+#ifdef CSR_SME_EMB
+ printk("CSR Embedded SME, API version: %d.%d\n",
+ SME_API_MAJOR_VERSION, SME_API_MINOR_VERSION);
+#endif
+#ifdef CSR_SME_USERSPACE
+#ifdef CSR_SUPPORT_WEXT
+ printk("CSR SME with WEXT support, API version: %d.%d\n",
+ SME_API_MAJOR_VERSION, SME_API_MINOR_VERSION);
+#else
+ printk("CSR SME, API version: %d.%d\n",
+ SME_API_MAJOR_VERSION, SME_API_MINOR_VERSION);
+#endif /* CSR_SUPPORT_WEXT */
+#endif /* CSR_SME_USERSPACE */
+#ifdef CSR_NATIVE_LINUX
+ printk("CSR native WEXT\n");
+#endif
+
+ /*
+ * Instantiate the /dev/unifi* device nodes.
+ * We must do this before registering with the SDIO driver because it
+ * will immediately call the "insert" callback if the card is
+ * already present.
+ */
+ r = uf_create_debug_device(&unifi_fops);
+ if (r) {
+ return r;
+ }
+
+ /* Now register with the SDIO driver */
+ r = uf_sdio_load();
+ if (r) {
+ uf_remove_debug_device();
+ return r;
+ }
+
+ return 0;
+} /* unifi_load() */
+
+
+void __exit
+unifi_unload(void)
+{
+ /* The SDIO remove hook will call unifi_disconnect(). */
+ uf_sdio_unload();
+
+ uf_remove_debug_device();
+
+} /* unifi_unload() */
+
+module_init(unifi_load);
+module_exit(unifi_unload);
+
+MODULE_DESCRIPTION("UniFi Device driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/firmware.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/firmware.c
new file mode 100644
index 0000000..4e1d65b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/firmware.c
@@ -0,0 +1,206 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: firmware.c
+ *
+ * PURPOSE:
+ * Example code for performing firmware download to UniFi.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <asm/uaccess.h>
+#include "driver/unifi.h"
+#include "driver/unifi_udi.h"
+#include "unifiio.h"
+#include "unifi_priv.h"
+
+
+#define UNIFIHELPER_INIT_MODE_SMEEMB 0
+#define UNIFIHELPER_INIT_MODE_SMEUSER 2
+#define UNIFIHELPER_INIT_MODE_NATIVE 1
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_run_unifihelper
+ *
+ * Ask userspace to send us firmware for download by running
+ * '/usr/sbin/unififw'.
+ * Derived from net_run_sbin_hotplug().
+ *
+ * Arguments:
+ * priv Pointer to OS private struct.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int
+uf_run_unifihelper(unifi_priv_t *priv)
+{
+#ifdef CONFIG_HOTPLUG
+
+#ifdef ANDROID_BUILD
+ char *prog = "/system/bin/unififw";
+#else
+ char *prog = "/usr/sbin/unififw";
+#endif /* ANDROID_BUILD */
+
+ char *argv[6], *envp[4];
+ char inst_str[8];
+ char init_mode[8];
+ int i, r;
+
+#if (defined CSR_SME_USERSPACE) && (!defined CSR_SUPPORT_WEXT)
+ unifi_trace(priv, UDBG1, "SME userspace build: run unifi_helper manually\n");
+ return 0;
+#endif
+
+ unifi_trace(priv, UDBG1, "starting %s\n", prog);
+
+ snprintf(inst_str, 8, "%d", priv->instance);
+#if (defined CSR_SME_EMB)
+ snprintf(init_mode, 8, "%d", UNIFIHELPER_INIT_MODE_SMEEMB);
+#elif (defined CSR_SME_USERSPACE)
+ snprintf(init_mode, 8, "%d", UNIFIHELPER_INIT_MODE_SMEUSER);
+#else
+ snprintf(init_mode, 8, "%d", UNIFIHELPER_INIT_MODE_NATIVE);
+#endif /* CSR_SME_EMB */
+
+ i = 0;
+ argv[i++] = prog;
+ argv[i++] = inst_str;
+ argv[i++] = init_mode;
+ argv[i++] = 0;
+ argv[i] = 0;
+ /* Don't add more args without making argv bigger */
+
+ /* minimal command environment */
+ i = 0;
+ envp[i++] = "HOME=/";
+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+ envp[i] = 0;
+ /* Don't add more without making envp bigger */
+
+ unifi_trace(priv, UDBG2, "running %s %s %s\n", argv[0], argv[1], argv[2]);
+
+ r = call_usermodehelper(argv[0], argv, envp, 0);
+
+ return r;
+#else
+ unifi_trace(priv, UDBG1, "Can't automatically download firmware because kernel does not have HOTPLUG\n");
+ return -1;
+#endif
+} /* uf_run_unifihelper() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_request_firmware_files
+ *
+ * Get the firmware files from userspace.
+ *
+ * Arguments:
+ * priv Pointer to OS private struct.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int uf_request_firmware_files(unifi_priv_t *priv)
+{
+ /* uses the default method to get the firmware */
+ const struct firmware *fw_entry;
+ int postfix;
+#define UNIFI_MAX_FW_PATH_LEN 32
+ char fw_name[UNIFI_MAX_FW_PATH_LEN];
+ int r;
+
+ /*
+ * The buffers for holding f/w images were allocated using vmalloc
+ * so must be freed with vfree.
+ */
+ if (priv->fw_loader.dl_data) {
+ vfree(priv->fw_loader.dl_data);
+ priv->fw_loader.dl_data = NULL;
+ priv->fw_loader.dl_len = 0;
+ }
+ if (priv->fw_sta.dl_data) {
+ vfree(priv->fw_sta.dl_data);
+ priv->fw_sta.dl_data = NULL;
+ priv->fw_sta.dl_len = 0;
+ }
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ if (priv->mib_data.length) {
+ vfree(priv->mib_data.data);
+ priv->mib_data.data = NULL;
+ priv->mib_data.length = 0;
+ }
+#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
+
+ postfix = priv->instance;
+
+ scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
+ postfix, "sta.xbv");
+ r = request_firmware(&fw_entry, fw_name, priv->unifi_device);
+ if (r == 0) {
+ priv->fw_sta.dl_data = vmalloc(fw_entry->size);
+ if (priv->fw_sta.dl_data == NULL)
+ {
+ unifi_error(priv,
+ "Failed to allocate memory for firmware image\n");
+ return -ENOMEM;
+ }
+
+ memcpy(priv->fw_sta.dl_data, fw_entry->data, fw_entry->size);
+ priv->fw_sta.dl_len = fw_entry->size;
+ release_firmware(fw_entry);
+ } else {
+ unifi_trace(priv, UDBG2, "Firmware file not available\n");
+ }
+
+ scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
+ postfix, "loader.xbv");
+ r = request_firmware(&fw_entry, fw_name, priv->unifi_device);
+ if (r == 0) {
+ priv->fw_loader.dl_data = vmalloc(fw_entry->size);
+ if (priv->fw_loader.dl_data == NULL)
+ {
+ unifi_error(priv,
+ "Failed to allocate memory for firmware loader image\n");
+ if (priv->fw_sta.dl_data) {
+ vfree(priv->fw_sta.dl_data);
+ priv->fw_sta.dl_data = NULL;
+ priv->fw_sta.dl_len = 0;
+ }
+ return -ENOMEM;
+ }
+
+ memcpy(priv->fw_loader.dl_data, fw_entry->data, fw_entry->size);
+ priv->fw_loader.dl_len = fw_entry->size;
+ release_firmware(fw_entry);
+ } else {
+ unifi_trace(priv, UDBG2, "Loader file not available\n");
+ }
+
+#ifdef CSR_SME_EMB
+ r = uf_request_mib_file(priv);
+ if (r) {
+ return r;
+ }
+
+ uf_request_mac_address_file(priv);
+#endif /* CSR_SME_EMB */
+
+ return 0;
+
+} /* uf_request_firmware_files() */
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/indications.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/indications.c
new file mode 100644
index 0000000..cac2d76
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/indications.c
@@ -0,0 +1,101 @@
+/*
+ * ***************************************************************************
+ * FILE: indications.c
+ *
+ * PURPOSE:
+ * Callbacks to process signals sent to us by the UniFi chip.
+ *
+ * This file is linux-specific.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_ma_unitdata_status_ind
+ *
+ * This function is called from the interrupt handler when a
+ * MA-UNITDATA-STATUS.indication is received from UniFi.
+ * This signal acknowledges transmission of a packet sent with
+ * MA-UNITDATA.request.
+ *
+ * Arguments:
+ * priv OS private context pointer.
+ * ind Pointer to signal structure received from UniFi.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_ma_unitdata_status_ind(unifi_priv_t *priv,
+ const CSR_MA_UNITDATA_CONFIRM *ind)
+{
+
+#if 0
+ printk("MA-UNITDATA.sts: D=%02X:%02X:%02X:%02X:%02X:%02X S=%02X:%02X:%02X:%02X:%02X:%02X\n",
+ ind->Da.x[0], ind->Da.x[1], ind->Da.x[2],
+ ind->Da.x[3], ind->Da.x[4], ind->Da.x[5],
+ ind->Sa.x[0], ind->Sa.x[1], ind->Sa.x[2],
+ ind->Sa.x[3], ind->Sa.x[4], ind->Sa.x[5]);
+ printk(" TransStatus=%d, Pri=%d, ServClass=%d, Tag=0x%08X\n",
+ ind->TransmissionStatus,
+ ind->ProvidedPriority,
+ ind->ProvidedServiceClass,
+ ind->ProvidedHostTag);
+#endif
+
+ /* update linux network stats */
+ if (ind->TransmissionStatus) {
+ /* failed */
+ switch (ind->TransmissionStatus) {
+ case 1: /* retry limit */
+#ifdef CSR_NATIVE_LINUX
+ priv->wext_conf.wireless_stats.discard.retries++;
+#endif
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ priv->wext_wireless_stats.discard.retries++;
+#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
+
+ /* Fall through - report in net dev stats too */
+
+ case 2: /* tx_lifetime */
+ case 11: /* tx EDCA timeout */
+ case 12: /* block ack timeout */
+ priv->stats.tx_aborted_errors++;
+ /* Fall through - report it as generic error too */
+
+ case 4: /* excessive data length */
+ case 5: /* non-null source routing */
+ case 6: /* unsupported priority */
+ case 7: /* unavailable priority */
+ case 8: /* unsupported service class */
+ case 9: /* unavailable service class */
+ case 10: /* unavailable key mapping */
+ priv->stats.tx_errors++;
+ break;
+ case 3: /* no_bss */
+ priv->stats.tx_carrier_errors++;
+ priv->stats.tx_errors++;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* tx_packets and tx_bytes are counted on send. */
+
+} /* unifi_ma_unitdata_status_ind() */
+
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/inet.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/inet.c
new file mode 100644
index 0000000..bf165ad
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/inet.c
@@ -0,0 +1,82 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: inet.c
+ *
+ * PURPOSE:
+ * Routines related to IP address changes.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/inetdevice.h>
+#include <linux/notifier.h>
+
+#include "unifi_priv.h"
+#include "driver/conversions.h"
+
+/*
+ * The inet notifier is global and not per-netdev. To avoid having a
+ * notifier registered when there are no unifi devices present, it's
+ * registered after the first unifi network device is registered, and
+ * unregistered when the last unifi network device is unregistered.
+ */
+
+static atomic_t inet_notif_refs = ATOMIC_INIT(0);
+
+static int unifi_inetaddr_event(struct notifier_block *notif, unsigned long event, void *ifa)
+{
+ struct net_device *ndev;
+ unifi_priv_t *priv;
+ struct in_ifaddr *if_addr;
+
+ ndev = ((struct in_ifaddr *)ifa)->ifa_dev->dev;
+ priv = ndev->priv;
+ if_addr = (struct in_ifaddr *)ifa;
+
+ /* If this event is for a UniFi device, notify the SME that an IP
+ * address has been added or removed. */
+ if (unifi_find_priv(priv) != -1) {
+ switch (event) {
+ case NETDEV_UP:
+ unifi_info(priv, "IP address assigned for %s\n", priv->netdev->name);
+ unifi_sys_ip_configured_ind(priv->smepriv, TRUE);
+ priv->sta_ip_address = UNPACK32(((uint8*)&if_addr->ifa_address), 0);
+#ifdef CSR_SUPPORT_WEXT
+ sme_mgt_packet_filter_set(priv);
+#endif
+ break;
+ case NETDEV_DOWN:
+ unifi_info(priv, "IP address removed for %s\n", priv->netdev->name);
+ unifi_sys_ip_configured_ind(priv->smepriv, FALSE);
+ priv->sta_ip_address = 0xFFFFFFFF;
+#ifdef CSR_SUPPORT_WEXT
+ sme_mgt_packet_filter_set(priv);
+#endif
+ break;
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block unifi_inetaddr_notifier = {
+ .notifier_call = unifi_inetaddr_event,
+};
+
+void unifi_register_inet_notifier(void)
+{
+ if (atomic_inc_return(&inet_notif_refs) == 1) {
+ register_inetaddr_notifier(&unifi_inetaddr_notifier);
+ }
+}
+
+void unifi_unregister_inet_notifier(void)
+{
+ if (atomic_dec_return(&inet_notif_refs) == 0) {
+ unregister_inetaddr_notifier(&unifi_inetaddr_notifier);
+ }
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/io.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/io.c
new file mode 100644
index 0000000..a866323
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/io.c
@@ -0,0 +1,706 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: io.c
+ *
+ * PURPOSE:
+ * This file contains routines that the SIDO driver can call when a
+ * UniFi card is first inserted (or detected) and removed.
+ *
+ * When used with sdioemb, the udev scripts (at least on Ubuntu) don't
+ * recognise a UniFi being added to the system. This is because sdioemb
+ * does not register itself as a device_driver, it uses it's own code
+ * to handle insert and remove.
+ * To have Ubuntu recognise UniFi, edit /etc/udev/rules.d/85-ifupdown.rules
+ * to change this line:
+ * SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
+ * to these:
+ * #SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
+ * SUBSYSTEM=="net", GOTO="net_start"
+ *
+ * Then you can add a stanza to /etc/network/interfaces like this:
+ * auto eth1
+ * iface eth1 inet dhcp
+ * wpa-conf /etc/wpa_supplicant.conf
+ * This will then automatically associate when a car dis inserted.
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/proc_fs.h>
+
+#include <driver/unifi.h>
+#include <driver/unifiversion.h>
+#include <driver/unifi_udi.h> /* for unifi_print_status() */
+#include "unifiio.h"
+#include "unifi_priv.h"
+
+
+/*
+ * Array of pointers to context structs for unifi devices that are present.
+ * The index in the array corresponds to the wlan interface number
+ * (if "wlan*" is used). If "eth*" is used, the eth* numbers are allocated
+ * after any Ethernet cards.
+ *
+ * The Arasan PCI-SDIO controller card supported by this driver has 2 slots,
+ * hence a max of 2 devices.
+ */
+static unifi_priv_t *Unifi_instances[MAX_UNIFI_DEVS];
+
+/*
+ * Array to hold the status of each unifi device in each slot.
+ * We only process an insert event when In_use[] for the slot is
+ * UNIFI_DEV_NOT_IN_USE. Otherwise, it means that the slot is in use or
+ * we are in the middle of a cleanup (the action on unplug).
+ */
+#define UNIFI_DEV_NOT_IN_USE 0
+#define UNIFI_DEV_IN_USE 1
+#define UNIFI_DEV_CLEANUP 2
+static int In_use[MAX_UNIFI_DEVS];
+/*
+ * Mutex to prevent UDI clients to open the character device before the priv
+ * is created and initialised.
+ */
+DECLARE_MUTEX(Unifi_instance_mutex);
+/*
+ * When the device is removed, unregister waits on Unifi_cleanup_wq
+ * until all the UDI clients release the character device.
+ */
+DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq);
+
+
+static int unifi_read_proc(char *page, char **start, off_t offset, int count,
+ int *eof, void *data);
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_register_netdev
+ *
+ * Registers the network interface, installes the qdisc,
+ * and registers the inet handler.
+ * In the porting exercise, register the driver to the network
+ * stack if necessary.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * O on success, non-zero otherwise.
+ *
+ * Notes:
+ * We will only unregister when the card is ejected, so we must
+ * only do it once.
+ * ---------------------------------------------------------------------------
+ */
+int
+uf_register_netdev(unifi_priv_t *priv)
+{
+ int r;
+
+ /*
+ * Allocates a device number and registers device with the network
+ * stack.
+ */
+ r = register_netdev(priv->netdev);
+ if (r) {
+ unifi_error(priv, "Failed to register net device\n");
+ return -EINVAL;
+ }
+
+ /* The device is registed */
+ priv->netdev_registered = 1;
+
+#ifdef CONFIG_NET_SCHED
+ /*
+ * IMPORTANT:
+ * uf_install_qdisc() holds the network device lock, we can not
+ * install the qdisk before the network device is registered.
+ */
+ r = uf_install_qdisc(priv->netdev);
+ if (r) {
+ unifi_error(priv, "Failed to install qdisc\n");
+ return r;
+ }
+#endif /* CONFIG_NET_SCHED */
+
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ /*
+ * Register the inet handler; it notifies us for changes in the IP address.
+ */
+ unifi_register_inet_notifier();
+#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
+
+ unifi_notice(priv, "unifi%d is %s\n",
+ priv->instance, priv->netdev->name);
+
+ return 0;
+} /* uf_register_netdev */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_unregister_netdev
+ *
+ * Unregisters the network interface and the inet handler.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * None.
+ *
+ * ---------------------------------------------------------------------------
+ */
+static void
+uf_unregister_netdev(unifi_priv_t *priv)
+{
+ if (priv->netdev_registered) {
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ /* Unregister the inet handler... */
+ unifi_unregister_inet_notifier();
+#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
+
+ /* ... and the netdev */
+ unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: unregister_netdev\n");
+ unregister_netdev(priv->netdev);
+ priv->netdev_registered = 0;
+ }
+
+} /* uf_unregister_netdev() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * register_unifi_sdio
+ *
+ * This function is called from the Probe (or equivalent) method of
+ * the SDIO driver when a UniFi card is detected.
+ * We allocate the Linux net_device struct, initialise the UniFi driver
+ * core, create the char device nodes and start the userspace helper
+ * to initialise the device.
+ *
+ * Arguments:
+ * sdio_dev Pointer to SDIO context handle to use for all
+ * SDIO ops.
+ * bus_id A small number indicating the SDIO card position on the
+ * bus. Typically this is the slot number, e.g. 0, 1 etc.
+ * Valid values are 0 to MAX_UNIFI_DEVS-1.
+ *
+ * Returns:
+ * Pointer to the unifi instance, or NULL on error.
+ * ---------------------------------------------------------------------------
+ */
+unifi_priv_t *
+register_unifi_sdio(void *sdio_dev, int bus_id, struct device *dev)
+{
+ unifi_priv_t *priv = NULL;
+ int r = -1;
+
+ func_enter();
+
+ if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
+ unifi_error(priv, "register_unifi_sdio: invalid device %d\n",
+ bus_id);
+ return NULL;
+ }
+
+ down(&Unifi_instance_mutex);
+
+ if (In_use[bus_id] != UNIFI_DEV_NOT_IN_USE) {
+ unifi_error(priv, "register_unifi_sdio: device %d is already in use\n",
+ bus_id);
+ goto failed0;
+ }
+
+
+ /* Allocate device private and net_device structs */
+ priv = unifi_alloc_netdevice(sdio_dev, bus_id);
+ if (priv == NULL) {
+ unifi_error(priv, "Failed to allocate driver private\n");
+ goto failed0;
+ }
+ priv->unifi_device = dev;
+
+ SET_NETDEV_DEV(priv->netdev, dev);
+
+ /* We are not ready to send data yet. */
+ netif_carrier_off(priv->netdev);
+
+ /* Allocate driver context. */
+ priv->card = unifi_alloc_card(priv->sdio, priv);
+ if (priv->card == NULL) {
+ unifi_error(priv, "Failed to allocate UniFi driver card struct.\n");
+ goto failed1;
+ }
+
+ if (Unifi_instances[bus_id]) {
+ unifi_error(priv, "Internal error: instance for slot %d is already taken\n",
+ bus_id);
+ }
+ Unifi_instances[bus_id] = priv;
+ In_use[bus_id] = UNIFI_DEV_IN_USE;
+
+ /* Create the character device nodes */
+ r = uf_create_device_nodes(priv, bus_id);
+ if (r) {
+ goto failed1;
+ }
+
+ /*
+ * We use the slot number as unifi device index.
+ */
+ snprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance);
+ if (!create_proc_read_entry(priv->proc_entry_name, 0, 0,
+ unifi_read_proc, (void *)priv->instance))
+ {
+ unifi_error(priv, "unifi: can't create /proc/driver/unifi\n");
+ }
+
+ /* Initialise the SME related threads and parameters */
+ r = uf_sme_init(priv);
+ if (r) {
+ unifi_error(priv, "SME initialisation failed.\n");
+ goto failed2;
+ }
+
+
+ /*
+ * Run the userspace helper program (unififw) to perform
+ * the device initialisation.
+ */
+ unifi_trace(priv, UDBG1, "run UniFi helper app...\n");
+ r = uf_run_unifihelper(priv);
+ if (r) {
+ unifi_notice(priv, "unable to run UniFi helper app\n");
+ /* Not a fatal error. */
+ }
+
+ up(&Unifi_instance_mutex);
+
+ func_exit();
+ return priv;
+
+
+failed2:
+ /* Remove the device nodes */
+ uf_destroy_device_nodes(priv);
+failed1:
+ /* Deregister priv->netdev_client */
+ ul_deregister_client(priv->netdev_client);
+
+failed0:
+ if (priv && priv->card) {
+ unifi_free_card(priv->card);
+ }
+ if (priv) {
+ unifi_free_netdevice(priv);
+ }
+
+ up(&Unifi_instance_mutex);
+
+ func_exit();
+ return NULL;
+} /* register_unifi_sdio() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ask_unifi_sdio_cleanup
+ *
+ * We can not free our private context, until all the char device
+ * clients have closed the file handles. unregister_unifi_sdio() which
+ * is called when a card is removed, waits on Unifi_cleanup_wq until
+ * the reference count becomes zero. It is time to wake it up now.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+ask_unifi_sdio_cleanup(unifi_priv_t *priv)
+{
+ func_enter();
+
+ /*
+ * Now clear the flag that says the old instance is in use.
+ * This is used to prevent a new instance being started before old
+ * one has finshed closing down, for example if bounce makes the card
+ * appear to be ejected and re-inserted quickly.
+ */
+ In_use[priv->instance] = UNIFI_DEV_CLEANUP;
+
+ unifi_trace(NULL, UDBG5, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n");
+ wake_up(&Unifi_cleanup_wq);
+
+ func_exit();
+
+} /* ask_unifi_sdio_cleanup() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * cleanup_unifi_sdio
+ *
+ * Release any resources owned by a unifi instance.
+ *
+ * Arguments:
+ * priv Pointer to the instance to free.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+cleanup_unifi_sdio(unifi_priv_t *priv)
+{
+ int priv_instance;
+
+ func_enter();
+
+ /* Remove the device nodes */
+ uf_destroy_device_nodes(priv);
+
+ /* Mark this device as gone away by NULLing the entry in Unifi_instances */
+ Unifi_instances[priv->instance] = NULL;
+
+ unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: remove_proc_entry\n");
+ /*
+ * Free the children of priv before unifi_free_netdevice() frees
+ * the priv struct
+ */
+ remove_proc_entry(priv->proc_entry_name, 0);
+
+ /* Unregister netdev as a client. */
+ if (priv->netdev_client) {
+ unifi_trace(priv, UDBG2, "Netdev client (id:%d s:0x%X) is unregistered\n",
+ priv->netdev_client->client_id, priv->netdev_client->sender_id);
+ ul_deregister_client(priv->netdev_client);
+ }
+
+ /* Destroy the SME related threads and parameters */
+ uf_sme_deinit(priv);
+
+ /*
+ * We need to free the resources held by the core, which include tx skbs,
+ * otherwise we can not call unregister_netdev().
+ */
+ if (priv->card) {
+ unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: free card\n");
+ unifi_free_card(priv->card);
+ priv->card = NULL;
+ }
+
+ /*
+ * Unregister the network device.
+ * We can not unregister the netdev before we release
+ * all pending packets in the core.
+ */
+ uf_unregister_netdev(priv);
+
+ unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: unifi_free_netdevice\n");
+ /*
+ * When unifi_free_netdevice() returns, the priv is invalid
+ * so we need to remember the instance to clear the global flag later.
+ */
+ priv_instance = priv->instance;
+
+ /* Priv is freed as part of the net_device */
+ unifi_free_netdevice(priv);
+
+ /*
+ * Now clear the flag that says the old instance is in use.
+ * This is used to prevent a new instance being started before old
+ * one has finshed closing down, for example if bounce makes the card
+ * appear to be ejected and re-inserted quickly.
+ */
+ In_use[priv_instance] = UNIFI_DEV_NOT_IN_USE;
+
+ unifi_trace(NULL, UDBG5, "cleanup_unifi_sdio: DONE.\n");
+
+ func_exit();
+
+} /* cleanup_unifi_sdio() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unregister_unifi_sdio
+ *
+ * Call from SDIO driver when it detects that UniFi has been removed.
+ *
+ * Arguments:
+ * bus_id Number of the card that was ejected.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unregister_unifi_sdio(int bus_id)
+{
+ unifi_priv_t *priv;
+ u8 reason = CONFIG_IND_EXIT;
+
+ if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
+ unifi_error(NULL, "unregister_unifi_sdio: invalid device %d\n",
+ bus_id);
+ return;
+ }
+
+ priv = Unifi_instances[bus_id];
+ if (priv == NULL) {
+ unifi_error(priv, "unregister_unifi_sdio: device %d is not registered\n",
+ bus_id);
+ func_exit();
+ return;
+ }
+
+ /* Stop the network traffic before freeing the core. */
+ netif_carrier_off(priv->netdev);
+ UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev);
+
+#ifdef CSR_NATIVE_LINUX
+ /*
+ * If the unifi thread was started, signal it to stop. This
+ * should cause any userspace processes with open unifi device to
+ * close them.
+ */
+ uf_stop_thread(priv, &priv->bh_thread);
+
+ /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */
+ unifi_abort_mlme(priv);
+#endif /* CSR_NATIVE_LINUX */
+
+ ul_log_config_ind(priv, &reason, sizeof(u8));
+
+ /* Deregister the UDI hook from the core. */
+ unifi_remove_udi_hook(priv->card, logging_handler);
+
+ unifi_put_instance(bus_id);
+
+ /*
+ * Wait until the device is cleaned up. i.e., when all userspace
+ * processes have closed any open unifi devices.
+ */
+ wait_event(Unifi_cleanup_wq, In_use[bus_id] == UNIFI_DEV_CLEANUP);
+ unifi_trace(NULL, UDBG5, "Received clean up event\n");
+
+ /* Now we can free the private context and the char device nodes */
+ cleanup_unifi_sdio(priv);
+
+} /* unregister_unifi_sdio() */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_find_instance
+ *
+ * Find the context structure for a given UniFi device instance.
+ *
+ * Arguments:
+ * inst The instance number to look for.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+unifi_priv_t *
+unifi_find_instance(int inst)
+{
+ if ((inst < 0) || (inst >= MAX_UNIFI_DEVS)) {
+ return NULL;
+ }
+ return Unifi_instances[inst];
+} /* unifi_find_instance() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_find_priv
+ *
+ * Find the device instance for a given context structure.
+ *
+ * Arguments:
+ * priv The context structure pointer to look for.
+ *
+ * Returns:
+ * index of instance, -1 otherwise.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_find_priv(unifi_priv_t *priv)
+{
+ int inst;
+
+ if (!priv) {
+ return -1;
+ }
+
+ for (inst = 0; inst < MAX_UNIFI_DEVS; inst++) {
+ if (Unifi_instances[inst] == priv) {
+ return inst;
+ }
+ }
+
+ return -1;
+} /* unifi_find_priv() */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_get_instance
+ *
+ * Find the context structure for a given UniFi device instance
+ * and increment the reference count.
+ *
+ * Arguments:
+ * inst The instance number to look for.
+ *
+ * Returns:
+ * Pointer to the instance or NULL if no instance exists.
+ * ---------------------------------------------------------------------------
+ */
+unifi_priv_t *
+unifi_get_instance(int inst)
+{
+ unifi_priv_t *priv;
+
+ down(&Unifi_instance_mutex);
+
+ priv = unifi_find_instance(inst);
+ if (priv) {
+ priv->ref_count++;
+ }
+
+ up(&Unifi_instance_mutex);
+
+ return priv;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_put_instance
+ *
+ * Decrement the context reference count, freeing resources and
+ * shutting down the driver when the count reaches zero.
+ *
+ * Arguments:
+ * inst The instance number to look for.
+ *
+ * Returns:
+ * Pointer to the instance or NULL if no instance exists.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_put_instance(int inst)
+{
+ unifi_priv_t *priv;
+
+ down(&Unifi_instance_mutex);
+
+ priv = unifi_find_instance(inst);
+ if (priv) {
+ priv->ref_count--;
+ if (priv->ref_count == 0) {
+ ask_unifi_sdio_cleanup(priv);
+ }
+ }
+
+ up(&Unifi_instance_mutex);
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_read_proc
+ *
+ * Read method for driver node in /proc/driver/unifi0
+ *
+ * Arguments:
+ * page
+ * start
+ * offset
+ * count
+ * eof
+ * data
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+#ifdef CONFIG_PROC_FS
+static int
+unifi_read_proc(char *page, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ unifi_priv_t *priv;
+ char *p = page;
+ int i;
+#ifdef CSR_SME_EMB
+ int r;
+ unifi_Versions sme_versions;
+#endif
+
+ priv = unifi_find_instance((int)data);
+ if (!priv) {
+ return 0;
+ }
+
+ if (offset == 0) {
+ p += unifi_sprintf(p, "UniFi SDIO Driver: v%s (build:%d) %s %s\n",
+ UNIFI_DRIVER_VERSION, UNIFI_DRIVER_BUILD_ID,
+ __DATE__, __TIME__);
+#ifdef CSR_SME_EMB
+ p += unifi_sprintf(p, "Driver/SME API version: %d.%d\n",
+ SME_API_MAJOR_VERSION, SME_API_MINOR_VERSION);
+ r = sme_mgt_get_versions(priv, &sme_versions);
+ if (r == 0) {
+ p += unifi_sprintf(p, "SME: CSR embedded build:%lu\n", sme_versions.smeBuild);
+ } else {
+ p += unifi_sprintf(p, "SME: CSR embedded build:unknown\n");
+ }
+#endif
+#ifdef CSR_SME_USERSPACE
+ p += unifi_sprintf(p, "SME: CSR userspace ");
+#ifdef CSR_SUPPORT_WEXT
+ p += unifi_sprintf(p, "with WEXT support\n");
+#else
+ p += unifi_sprintf(p, "\n");
+#endif /* CSR_SUPPORT_WEXT */
+#endif /* CSR_SME_USERSPACE */
+#ifdef CSR_NATIVE_LINUX
+ p += unifi_sprintf(p, "SME: native\n");
+#endif
+
+ p += unifi_print_status(priv->card, p);
+
+ p += unifi_sprintf(p, "Last dbg str: %s\n", priv->last_debug_string);
+
+ p += unifi_sprintf(p, "Last dbg16:");
+ for (i = 0; i < 8; i++) {
+ p += unifi_sprintf(p, " %04X", priv->last_debug_word16[i]);
+ }
+ p += unifi_sprintf(p, "\n");
+ p += unifi_sprintf(p, " ");
+ for (; i < 16; i++) {
+ p += unifi_sprintf(p, " %04X", priv->last_debug_word16[i]);
+ }
+ p += unifi_sprintf(p, "\n");
+ } else {
+ *eof = 1;
+ }
+
+ return (p - page);
+} /* unifi_read_proc() */
+#endif
+
+
+
+EXPORT_SYMBOL(register_unifi_sdio);
+EXPORT_SYMBOL(unregister_unifi_sdio);
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/monitor.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/monitor.c
new file mode 100644
index 0000000..6514453
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/monitor.c
@@ -0,0 +1,453 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: monitor.c
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#include "unifi_priv.h"
+
+#ifdef UNIFI_SNIFF_ARPHRD
+
+
+#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP)
+#include <net/ieee80211_radiotap.h>
+#include <net/ieee80211.h>
+#endif
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW ETH_P_ALL
+#endif
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_start_sniff
+ *
+ * Start UniFi capture in SNIFF mode, i.e capture everything it hears.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ *
+ * Returns:
+ * 0 on success or kernel error code
+ * ---------------------------------------------------------------------------
+ */
+int
+uf_start_sniff(unifi_priv_t *priv)
+{
+ ul_client_t *pcli = priv->wext_client;
+ CSR_SIGNAL signal;
+ CSR_MLME_SNIFFJOIN_REQUEST *req = &signal.u.MlmeSniffjoinRequest;
+ int timeout = 1000;
+ int r;
+
+ req->Ifindex = priv->if_index;
+ req->Channel = priv->wext_conf.channel;
+ req->ChannelStartingFactor = 0;
+
+#if 0
+ printk("SniffJoin: Ifindex=%d, Channel=%d, ChannelStartingFactor=%d\n",
+ req->Ifindex,
+ req->Channel,
+ req->ChannelStartingFactor);
+#endif
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SNIFFJOIN_REQUEST_ID;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, NULL, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send SNIFFJOIN request, error %d\n", r);
+ return r;
+ }
+
+ r = pcli->reply_signal->u.MlmeSniffjoinConfirm.Resultcode;
+ if (r) {
+ unifi_notice(priv, "SNIFFJOIN request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ return -EIO;
+ }
+
+ return 0;
+} /* uf_start_sniff() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * netrx_radiotap
+ *
+ * Reformat a UniFi SNIFFDATA signal into a radiotap packet.
+ *
+ * Arguments:
+ * priv OS private context pointer.
+ * ind Pointer to a MA_UNITDATA_INDICATION or
+ * DS_UNITDATA_INDICATION indication structure.
+ *
+ * Notes:
+ * Radiotap header values are all little-endian, UniFi signals will have
+ * been converted to host-endian.
+ * ---------------------------------------------------------------------------
+ */
+#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP)
+static void
+netrx_radiotap(unifi_priv_t *priv,
+ const CSR_MA_SNIFFDATA_INDICATION *ind,
+ struct sk_buff *skb_orig)
+{
+ struct net_device *dev = priv->netdev;
+ struct sk_buff *skb = NULL;
+ unsigned char *ptr;
+ unsigned char *base;
+ int ind_data_len = skb_orig->len - 2 - ETH_HLEN;
+ struct unifi_rx_radiotap_header {
+ struct ieee80211_radiotap_header rt_hdr;
+ /* IEEE80211_RADIOTAP_TSFT */
+ u64 rt_tsft;
+ /* IEEE80211_RADIOTAP_FLAGS */
+ u8 rt_flags;
+ /* IEEE80211_RADIOTAP_RATE */
+ u8 rt_rate;
+ /* IEEE80211_RADIOTAP_CHANNEL */
+ u16 rt_chan;
+ u16 rt_chan_flags;
+ /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
+ u8 rt_dbm_antsignal;
+ /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
+ u8 rt_dbm_antnoise;
+ /* IEEE80211_RADIOTAP_ANTENNA */
+ u8 rt_antenna;
+
+ /* pad to 4-byte boundary */
+ u8 pad[3];
+ } __attribute__((__packed__));
+
+ struct unifi_rx_radiotap_header *unifi_rt;
+ int signal, noise, snr;
+
+ func_enter();
+
+ if (ind_data_len <= 0) {
+ unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n");
+ return;
+ }
+
+ /*
+ * Allocate a SKB for the received data packet, including radiotap
+ * header.
+ */
+ skb = dev_alloc_skb(ind_data_len + sizeof(struct unifi_rx_radiotap_header) + 4);
+ if (! skb) {
+ unifi_error(priv, "alloc_skb failed.\n");
+ priv->stats.rx_errors++;
+ return;
+ }
+
+ base = skb->data;
+
+ /* Reserve the radiotap header at the front of skb */
+ unifi_rt = (struct unifi_rx_radiotap_header *)
+ skb_put(skb, sizeof(struct unifi_rx_radiotap_header));
+
+ /* Copy in the 802.11 frame */
+ ptr = skb_put(skb, ind_data_len);
+ memcpy(ptr, skb_orig->data, ind_data_len);
+
+ unifi_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+ unifi_rt->rt_hdr.it_pad = 0; /* always good to zero */
+ unifi_rt->rt_hdr.it_len = sizeof(struct unifi_rx_radiotap_header);
+
+ /* Big bitfield of all the fields we provide in radiotap */
+ unifi_rt->rt_hdr.it_present = 0
+ | (1 << IEEE80211_RADIOTAP_TSFT)
+ | (1 << IEEE80211_RADIOTAP_FLAGS)
+ | (1 << IEEE80211_RADIOTAP_RATE)
+ | (1 << IEEE80211_RADIOTAP_CHANNEL)
+ | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)
+ | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)
+ | (1 << IEEE80211_RADIOTAP_ANTENNA)
+ ;
+
+
+ /* No flags to set */
+ unifi_rt->rt_tsft = ind->Timestamp;
+
+ unifi_rt->rt_flags = 0;
+
+ unifi_rt->rt_rate = ind->Rate;
+
+ unifi_rt->rt_chan = cpu_to_le16(ieee80211chan2mhz(priv->wext_conf.channel));
+ unifi_rt->rt_chan_flags = 0;
+
+ /* Convert signal to dBm */
+ signal = (s16)unifi2host_16(ind->Rssi); /* in dBm */
+ snr = (s16)unifi2host_16(ind->Snr); /* in dB */
+ noise = signal - snr;
+
+ unifi_rt->rt_dbm_antsignal = signal;
+ unifi_rt->rt_dbm_antnoise = noise;
+
+ unifi_rt->rt_antenna = ind->AntennaId;
+
+
+#if 0
+ printk("skb datalen=%d\n", skb->len);
+ dump(skb->data, 48);
+#endif
+
+ skb->dev = dev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+ skb->mac_header = skb->data;
+#else
+ skb->mac.raw = skb->data;
+#endif
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = __constant_htons(ETH_P_80211_RAW);
+ memset(skb->cb, 0, sizeof(skb->cb));
+
+ /* Pass up to Linux network stack */
+ netif_rx(skb);
+
+ dev->last_rx = jiffies;
+
+ /* Bump the rx stats */
+ priv->stats.rx_packets++;
+ priv->stats.rx_bytes += ind_data_len;
+
+ func_exit();
+} /* netrx_radiotap() */
+#endif /* RADIOTAP */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * netrx_prism
+ *
+ * Reformat a UniFi SNIFFDATA signal into a Prism format sniff packet.
+ *
+ * Arguments:
+ * priv OS private context pointer.
+ * ind Pointer to a MA_UNITDATA_INDICATION or
+ * DS_UNITDATA_INDICATION indication structure.
+ *
+ * Notes:
+ * Radiotap header values are all little-endian, UniFi signals will have
+ * been converted to host-endian.
+ * ---------------------------------------------------------------------------
+ */
+#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_PRISM)
+static void
+netrx_prism(unifi_priv_t *priv,
+ const CSR_MA_SNIFFDATA_INDICATION *ind,
+ struct sk_buff *skb_orig)
+{
+ struct net_device *dev = priv->netdev;
+ struct sk_buff *skb = NULL;
+ unsigned char *ptr;
+ unsigned char *base;
+ int ind_data_len = skb_orig->len - 2 - ETH_HLEN;
+#define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
+#define WLANCAP_MAGIC_COOKIE_V1 0x80211001
+#define WLANCAP_MAGIC_COOKIE_V2 0x80211002
+ struct avs_header_v1 {
+ uint32 version;
+ uint32 length;
+ uint64 mactime;
+ uint64 hosttime;
+ uint32 phytype;
+ uint32 channel;
+ uint32 datarate;
+ uint32 antenna;
+ uint32 priority;
+ uint32 ssi_type;
+ int32 ssi_signal;
+ int32 ssi_noise;
+ uint32 preamble;
+ uint32 encoding;
+ } *avs;
+ int signal, noise, snr;
+
+ func_enter();
+
+ if (ind_data_len <= 0) {
+ unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n");
+ return;
+ }
+
+#if 0
+ printk("MA-SINFFDATA.ind: DataLen=%d bytes, TSF %02X %02X %02X %02X %02X %02X %02X %02X, Rate=%d, Antenna=%d\n",
+ ind->Data.DataLength,
+ (unsigned int)(ind->Timestamp & 0xFF),
+ (unsigned int)((ind->Timestamp >> 8) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 16) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 24) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 32) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 40) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 48) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 56) & 0xFF),
+ ind->Rate,
+ ind->Antenna);
+
+ printk("payload, len %d\n", length);
+ dump((unsigned char *)payload, 32);
+#endif
+
+ /*
+ * Allocate a SKB for the received data packet, including radiotap
+ * header.
+ */
+ skb = dev_alloc_skb(ind_data_len + sizeof(struct avs_header_v1) + 4);
+ if (! skb) {
+ unifi_error(priv, "alloc_skb failed.\n");
+ priv->stats.rx_errors++;
+ return;
+ }
+
+ base = skb->data;
+
+ /* Reserve the radiotap header at the front of skb */
+ avs = (struct avs_header_v1 *)skb_put(skb, sizeof(struct avs_header_v1));
+
+ /* Copy in the 802.11 frame */
+ ptr = skb_put(skb, ind_data_len);
+ memcpy(ptr, skb_orig->data, ind_data_len);
+
+ /* Convert signal to dBm */
+ signal = 0x10000 - ((s16)unifi2host_16(ind->Rssi)); /* in dBm */
+ snr = (s16)unifi2host_16(ind->Snr); /* in dB */
+ noise = signal - snr;
+
+ avs->version = htonl(WLANCAP_MAGIC_COOKIE_V1);
+ avs->length = htonl(sizeof(struct avs_header_v1));
+ avs->mactime = __cpu_to_be64(ind->Timestamp);
+ avs->hosttime = __cpu_to_be64(jiffies);
+ avs->phytype = htonl(9); /* dss_ofdm_dot11_g */
+ avs->channel = htonl(priv->wext_conf.channel);
+ avs->datarate = htonl(ind->Rate * 5);
+ avs->antenna = htonl(ind->Antenna);
+ avs->priority = htonl(0); /* unknown */
+ avs->ssi_type = htonl(2); /* dBm */
+ avs->ssi_signal = htonl(signal);
+ avs->ssi_noise = htonl(noise);
+ avs->preamble = htonl(0); /* unknown */
+ avs->encoding = htonl(0); /* unknown */
+
+
+#if 0
+ printk("skb datalen=%d\n", skb->len);
+ dump(skb->data, 48);
+#endif
+
+ skb->dev = dev;
+ skb->mac.raw = skb->data;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = __constant_htons(ETH_P_80211_RAW);
+ memset(skb->cb, 0, sizeof(skb->cb));
+
+ /* Pass up to Linux network stack */
+ netif_rx(skb);
+
+ dev->last_rx = jiffies;
+
+ /* Bump the rx stats */
+ priv->stats.rx_packets++;
+ priv->stats.rx_bytes += ind_data_len;
+
+ func_exit();
+} /* netrx_prism() */
+#endif /* PRISM */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ma_sniffdata_ind
+ *
+ * Reformat a UniFi SNIFFDATA signal into a network
+ *
+ * Arguments:
+ * ospriv OS private context pointer.
+ * ind Pointer to a MA_UNITDATA_INDICATION or
+ * DS_UNITDATA_INDICATION indication structure.
+ * bulkdata Pointer to a bulk data structure, describing
+ * the data received.
+ *
+ * Notes:
+ * Radiotap header values are all little-endian, UniFi signals will have
+ * been converted to host-endian.
+ * ---------------------------------------------------------------------------
+ */
+void
+ma_sniffdata_ind(void *ospriv,
+ const CSR_MA_SNIFFDATA_INDICATION *ind,
+ const bulk_data_param_t *bulkdata)
+{
+ unifi_priv_t *priv = ospriv;
+ struct net_device *dev = priv->netdev;
+ struct sk_buff *skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
+
+ func_enter();
+
+ if (bulkdata->d[0].data_length == 0) {
+ unifi_warning(priv, "rx: MA-SNIFFDATA indication with zero bulk data\n");
+ func_exit();
+ return;
+ }
+
+#if 0
+ printk("MA-SNIFFDATA.ind: DataLen=%d bytes, TSF %02X %02X %02X %02X %02X %02X %02X %02X, Rate=%d, Antenna=%d\n",
+ ind->Data.DataLength,
+ (unsigned int)(ind->Timestamp & 0xFF),
+ (unsigned int)((ind->Timestamp >> 8) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 16) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 24) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 32) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 40) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 48) & 0xFF),
+ (unsigned int)((ind->Timestamp >> 56) & 0xFF),
+ ind->Rate,
+ ind->Antenna);
+
+ printk("payload, len %d\n", length);
+ dump((unsigned char *)payload, 32);
+#endif
+
+ /* We only process data packets if the interface is open */
+ if (unlikely(!netif_running(dev))) {
+ priv->stats.rx_dropped++;
+ priv->wext_conf.wireless_stats.discard.misc++;
+#if 0
+ printk("Dropping packet while interface is not up.\n");
+#endif
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ if (ind->ReceptionStatus) {
+ priv->stats.rx_dropped++;
+ priv->wext_conf.wireless_stats.discard.misc++;
+ printk(KERN_INFO "unifi: Dropping corrupt sniff packet\n");
+ dev_kfree_skb(skb);
+ return;
+ }
+
+#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_PRISM)
+ netrx_prism(priv, ind, skb);
+#endif /* PRISM */
+
+#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP)
+ netrx_radiotap(priv, ind, skb);
+#endif /* RADIOTAP */
+
+ dev_kfree_skb(skb);
+
+} /* ma_sniffdata_ind() */
+
+
+#endif /* UNIFI_SNIFF_ARPHRD */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/netdev.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/netdev.c
new file mode 100644
index 0000000..8faa885
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/netdev.c
@@ -0,0 +1,1699 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: netdev.c
+ *
+ * PURPOSE:
+ * This file provides the upper edge interface to the linux netdevice
+ * and wireless extensions.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/types.h>
+#include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
+#include "driver/unifi.h"
+#include "driver/conversions.h"
+#include "unifi_priv.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
+#include <net/ieee80211.h>
+#else
+#include <net/iw_handler.h>
+#endif
+#include <net/pkt_sched.h>
+
+#ifndef P80211_OUI_LEN
+#define P80211_OUI_LEN 3
+#endif
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888e
+#endif
+
+
+#define ieee2host16(n) __le16_to_cpu(n)
+#define ieee2host32(n) __le32_to_cpu(n)
+#define host2ieee16(n) __cpu_to_le16(n)
+#define host2ieee32(n) __cpu_to_le32(n)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#ifdef UNIFI_NET_NAME
+#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
+ do { \
+ static uint8 name[8]; \
+ sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \
+ _dev = alloc_netdev_mq(_size, name, _setup, _num_of_queues); \
+ } while (0);
+#else
+#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
+ do { \
+ _dev = alloc_etherdev_mq(_size, _num_of_queues); \
+ } while (0);
+#endif /* UNIFI_NET_NAME */
+#else
+#ifdef UNIFI_NET_NAME
+#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
+ do { \
+ static uint8 name[8]; \
+ sprintf(name, "%s%s", UNIFI_NET_NAME, _name); \
+ _dev = alloc_netdev(_size, name, _setup); \
+ } while (0);
+#else
+#define UF_ALLOC_NETDEV(_dev, _size, _name, _setup, _num_of_queues) \
+ do { \
+ _dev = alloc_etherdev(_size); \
+ } while (0);
+#endif /* UNIFI_NET_NAME */
+#endif /* LINUX_VERSION_CODE */
+
+
+typedef struct {
+ u8 dsap; /* always 0xAA */
+ u8 ssap; /* always 0xAA */
+ u8 ctrl; /* always 0x03 */
+ u8 oui[P80211_OUI_LEN]; /* organizational universal id */
+ u16 protocol;
+} __attribute__ ((packed)) llc_snap_hdr_t;
+
+/* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */
+#ifdef CSR_SUPPORT_WEXT
+extern struct iw_handler_def unifi_iw_handler_def;
+#endif /* CSR_SUPPORT_WEXT */
+
+static int unifi_net_open(struct net_device *dev);
+static int unifi_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int unifi_net_stop(struct net_device *dev);
+static struct net_device_stats *unifi_net_get_stats(struct net_device *dev);
+static int unifi_net_xmit(struct sk_buff *skb, struct net_device *dev);
+static void unifi_set_multicast_list(struct net_device *dev);
+static unifi_PortAction verify_port(unifi_priv_t *priv, unsigned char *address);
+
+
+#ifdef CONFIG_NET_SCHED
+/*
+ * Queueing Discipline Interface
+ * Only used if kernel is configured with CONFIG_NET_SCHED
+ */
+
+/*
+ * The driver uses the qdisc interface to buffer and control all
+ * outgoing traffic. We create a root qdisc, register our qdisc operations
+ * and later we create two subsiduary pfifo queues for the uncontrolled
+ * and controlled ports.
+ *
+ * The network stack delivers all outgoing packets in our enqueue handler.
+ * There, we classify the packet and decide whether to store it or drop it
+ * (if the controlled port state is set to "discard").
+ * If the packet is enqueued, the network stack call our dequeue handler.
+ * There, we decide whether we can send the packet, delay it or drop it
+ * (the controlled port configuration might have changed meanwhile).
+ * If a packet is dequeued, then the network stack calls our hard_start_xmit
+ * handler where finally we send the packet.
+ *
+ * If the hard_start_xmit handler fails to send the packet, we return
+ * NETDEV_TX_BUSY and the network stack call our requeue handler where
+ * we put the packet back in the same queue in came from.
+ *
+ */
+#define UF_QDISK_MAX_QUEUES 2
+#define UF_QDISK_UNCONTROLLED_QUEUE 0
+#define UF_QDISK_CONTROLLED_QUEUE 1
+
+struct uf_sched_data
+{
+ /* Traffic Classifier TBD */
+ struct tcf_proto *filter_list;
+ /* Our two queues */
+ struct Qdisc *queues[UF_QDISK_MAX_QUEUES];
+};
+
+
+struct uf_tx_packet_data {
+ /* Store the queue the packet is stored to */
+ unsigned int queue;
+ /* Debug */
+ unsigned long host_tag;
+};
+
+static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd);
+static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd);
+static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd);
+static void uf_qdiscop_reset(struct Qdisc* qd);
+static void uf_qdiscop_destroy(struct Qdisc* qd);
+static int uf_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt);
+static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt);
+#else
+static int uf_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt);
+static int uf_qdiscop_init(struct Qdisc *qd, struct rtattr *opt);
+#endif
+
+
+/* queueing discipline operations */
+static struct Qdisc_ops uf_qdisc_ops =
+{
+ .next = NULL,
+ .cl_ops = NULL,
+ .id = "UniFi Qdisc",
+ .priv_size = sizeof(struct uf_sched_data),
+
+ .enqueue = uf_qdiscop_enqueue,
+ .dequeue = uf_qdiscop_dequeue,
+ .requeue = uf_qdiscop_requeue,
+ .drop = NULL, /* drop not needed since we are always the root qdisc */
+
+ .init = uf_qdiscop_init,
+ .reset = uf_qdiscop_reset,
+ .destroy = uf_qdiscop_destroy,
+ .change = uf_qdiscop_tune,
+
+ .dump = uf_qdiscop_dump,
+};
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \
+ qdisc_create_dflt(dev, netdev_get_tx_queue(_dev, 0), _ops, _root)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \
+ qdisc_create_dflt(dev, _ops, _root)
+#else
+#define UF_QDISC_CREATE_DFLT(_dev, _ops, _root) \
+ qdisc_create_dflt(dev, _ops)
+#endif /* LINUX_VERSION_CODE */
+
+#endif /* CONFIG_NET_SCHED */
+
+
+static u8 oui_rfc1042[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
+static u8 oui_8021h[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
+
+
+/* Callback for event logging to blocking clients */
+static void netdev_mlme_event_handler(ul_client_t *client,
+ u8 *sig_packed, int sig_len,
+ const bulk_data_param_t *bulkdata,
+ int dir);
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_alloc_netdevice
+ *
+ * Allocate memory for the net_device and device private structs
+ * for this interface.
+ * Fill in the fields, but don't register the interface yet.
+ * We need to configure the UniFi first.
+ *
+ * Arguments:
+ * sdio_dev Pointer to SDIO context handle to use for all
+ * SDIO ops.
+ * bus_id A small number indicating the SDIO card position on the
+ * bus. Typically this is the slot number, e.g. 0, 1 etc.
+ * Valid values are 0 to MAX_UNIFI_DEVS-1.
+ *
+ * Returns:
+ * Pointer to device private struct.
+ *
+ * Notes:
+ * The net_device and device private structs are allocated together
+ * and should be freed by freeing the net_device pointer.
+ * ---------------------------------------------------------------------------
+ */
+unifi_priv_t *
+unifi_alloc_netdevice(void *sdio_dev, int bus_id)
+{
+ struct net_device *dev;
+ unifi_priv_t *priv;
+
+ /*
+ * Allocate netdevice struct, assign name template and
+ * setup as an ethernet device.
+ * The net_device and private structs are zeroed. Ether_setup() then
+ * sets up ethernet handlers and values.
+ * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
+ * so use "eth*" (like other wireless extns drivers).
+ */
+ UF_ALLOC_NETDEV(dev, sizeof(unifi_priv_t), "%d", ether_setup, 1);
+ if (dev == NULL) {
+ return NULL;
+ }
+
+
+ /* Set up back pointer from priv to netdev */
+ priv = netdev_priv(dev);
+ priv->netdev = dev;
+
+
+ /* Setup / override net_device fields */
+ dev->open = unifi_net_open;
+ dev->stop = unifi_net_stop;
+ dev->hard_start_xmit = unifi_net_xmit;
+ dev->do_ioctl = unifi_net_ioctl;
+
+ /* called by /proc/net/dev */
+ dev->get_stats = unifi_net_get_stats;
+
+ dev->set_multicast_list = unifi_set_multicast_list;
+
+#ifdef CSR_SUPPORT_WEXT
+ dev->wireless_handlers = &unifi_iw_handler_def;
+#if IW_HANDLER_VERSION < 6
+ dev->get_wireless_stats = unifi_get_wireless_stats;
+#endif /* IW_HANDLER_VERSION */
+#endif /* CSR_SUPPORT_WEXT */
+
+ /* Use bus_id as instance number */
+ priv->instance = bus_id;
+ /* Store SDIO pointer to pass in the core */
+ priv->sdio = sdio_dev;
+
+ /* Consider UniFi to be uninitialised */
+ priv->init_progress = UNIFI_INIT_NONE;
+
+ /*
+ * Initialise the clients structure array.
+ * We do not need protection around ul_init_clients() because
+ * the character device can not be used until unifi_alloc_netdevice()
+ * returns and Unifi_instances[bus_id]=priv is set, since unifi_open()
+ * will return -ENODEV.
+ */
+ ul_init_clients(priv);
+
+ /* Register a new ul client to send the multicast list signals. */
+ priv->netdev_client = ul_register_client(priv,
+ 0,
+ netdev_mlme_event_handler);
+ if (priv->netdev_client == NULL) {
+ unifi_error(priv,
+ "Failed to register a unifi client for background netdev processing\n");
+ free_netdev(priv->netdev);
+ return NULL;
+ }
+ unifi_trace(priv, UDBG2, "Netdev client (id:%d s:0x%X) is registered\n",
+ priv->netdev_client->client_id, priv->netdev_client->sender_id);
+
+ priv->sta_wmm_capabilities = 0;
+
+ /*
+ * Initialise the OS private struct.
+ */
+ /*
+ * Instead of deciding in advance to use 11bg or 11a, we could do a more
+ * clever scan on both radios.
+ */
+ if (use_5g) {
+ priv->if_index = CSR_INDEX_5G;
+ unifi_info(priv, "Using the 802.11a radio\n");
+ } else {
+ priv->if_index = CSR_INDEX_2G4;
+ }
+
+ /* Initialise bh thread structure */
+ priv->bh_thread.thread_task = NULL;
+ init_waitqueue_head(&priv->bh_thread.wakeup_q);
+ priv->bh_thread.wakeup_flag = 0;
+ unifi_sprintf(priv->bh_thread.name, "uf_bh_thread");
+
+ priv->connected = UnifiConnectedUnknown; /* -1 unknown, 0 no, 1 yes */
+
+#ifdef USE_DRIVER_LOCK
+ init_MUTEX(&priv->lock);
+#endif /* USE_DRIVER_LOCK */
+
+ spin_lock_init(&priv->send_signal_lock);
+
+ /* Create the Traffic Analysis workqueue */
+ priv->unifi_workqueue = create_singlethread_workqueue("unifi_workq");
+ if (priv->unifi_workqueue == NULL) {
+ /* Deregister priv->netdev_client */
+ ul_deregister_client(priv->netdev_client);
+ free_netdev(priv->netdev);
+ return NULL;
+ }
+ /* Create the Multicast Addresses list work structure */
+ INIT_WORK(&priv->multicast_list_task, uf_multicast_list_wq);
+
+#ifdef CONFIG_NET_SCHED
+ /* Register the qdisc operations */
+ register_qdisc(&uf_qdisc_ops);
+#endif /* CONFIG_NET_SCHED */
+
+ priv->ref_count = 1;
+
+
+ priv->amp_client = NULL;
+
+ return priv;
+} /* unifi_alloc_netdevice() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_free_netdevice
+ *
+ * Unregister the network device and free the memory allocated for it.
+ * NB This includes the memory for the priv struct.
+ *
+ * Arguments:
+ * priv Device private pointer.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_free_netdevice(unifi_priv_t *priv)
+{
+ func_enter();
+
+ if (!priv) {
+ return -EINVAL;
+ }
+
+ /*
+ * The buffers for holding f/w images were allocated using vmalloc
+ * so must be freed with vfree.
+ */
+ if (priv->fw_loader.dl_data) {
+ vfree(priv->fw_loader.dl_data);
+ }
+ priv->fw_loader.dl_data = NULL;
+ priv->fw_loader.dl_len = 0;
+ if (priv->fw_sta.dl_data) {
+ vfree(priv->fw_sta.dl_data);
+ }
+ priv->fw_sta.dl_data = NULL;
+ priv->fw_sta.dl_len = 0;
+
+#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
+ if (priv->connection_config.mlmeAssociateReqInformationElements.data) {
+ kfree(priv->connection_config.mlmeAssociateReqInformationElements.data);
+ }
+ priv->connection_config.mlmeAssociateReqInformationElements.data = NULL;
+ priv->connection_config.mlmeAssociateReqInformationElements.length = 0;
+
+ if (priv->mib_data.length) {
+ vfree(priv->mib_data.data);
+ }
+ priv->mib_data.data = NULL;
+ priv->mib_data.length = 0;
+
+#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
+
+
+#ifdef CONFIG_NET_SCHED
+ /* Unregister the qdisc operations */
+ unregister_qdisc(&uf_qdisc_ops);
+#endif /* CONFIG_NET_SCHED */
+
+ /* Cancel work items and destroy the workqueue */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ cancel_work_sync(&priv->multicast_list_task);
+#endif
+ flush_workqueue(priv->unifi_workqueue);
+ destroy_workqueue(priv->unifi_workqueue);
+
+ /* Free the netdev struct and priv, which are all one lump. */
+ free_netdev(priv->netdev);
+
+ func_exit();
+ return 0;
+} /* unifi_free_netdevice() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_net_open
+ *
+ * Called when userland does "ifconfig wlan0 up".
+ *
+ * Arguments:
+ * dev Device pointer.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_net_open(struct net_device *dev)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ func_enter();
+
+ /* If we haven't finished UniFi initialisation, we can't start */
+ if (priv->init_progress != UNIFI_INIT_COMPLETED) {
+ unifi_trace(priv, UDBG1, "%s: unifi not ready, failing net_open\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+#if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD)
+ /*
+ * To sniff, the user must do "iwconfig mode monitor", which sets
+ * priv->wext_conf.mode to IW_MODE_MONITOR.
+ * Then he/she must do "ifconfig ethn up", which calls this fn.
+ * There is no point in starting the sniff with SNIFFJOIN until
+ * this point.
+ */
+ if (priv->wext_conf.mode == IW_MODE_MONITOR) {
+ int err;
+ err = uf_start_sniff(priv);
+ if (err) {
+ return err;
+ }
+ netif_carrier_on(dev);
+ }
+#endif
+
+ UF_NETIF_TX_START_ALL_QUEUES(dev);
+
+ func_exit();
+ return 0;
+} /* unifi_net_open() */
+
+
+static int
+unifi_net_stop(struct net_device *dev)
+{
+#ifdef CSR_NATIVE_LINUX
+ unifi_priv_t *priv = dev->priv;
+#endif
+
+ func_enter();
+
+#ifdef CSR_NATIVE_LINUX
+ /* Stop sniffing if in Monitor mode */
+ if (priv->wext_conf.mode == IW_MODE_MONITOR) {
+ if (priv->card) {
+ int err;
+ err = unifi_reset_state(priv, dev->dev_addr, 1);
+ if (err) {
+ return err;
+ }
+ }
+ }
+#endif
+
+ UF_NETIF_TX_STOP_ALL_QUEUES(dev);
+
+ func_exit();
+ return 0;
+} /* unifi_net_stop() */
+
+
+/* This is called after the WE handlers */
+static int
+unifi_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ int rc;
+
+ rc = -EOPNOTSUPP;
+
+ return rc;
+} /* unifi_net_ioctl() */
+
+
+
+static struct net_device_stats *
+unifi_net_get_stats(struct net_device *dev)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ return &priv->stats;
+} /* unifi_net_get_stats() */
+
+
+
+static int
+skb_ether_to_80211(struct net_device *dev, struct sk_buff *skb, int proto)
+{
+ llc_snap_hdr_t *snap;
+
+ /* step 1: classify ether frame, DIX or 802.3? */
+
+ if (proto < 0x600) {
+ /* codes <= 1500 reserved for 802.3 lengths */
+ /* it's 802.3, pass ether payload unchanged, */
+ unifi_trace(dev->priv, UDBG3, "802.3 len: %d\n", skb->len);
+
+ /* leave off any PAD octets. */
+ skb_trim(skb, proto);
+ } else if (proto == ETH_P_8021Q) {
+ /* Store the VLAN SNAP (should be 87-65). */
+ u16 vlan_snap = *(u16*)skb->data;
+ /* Add AA-AA-03-00-00-00 */
+ snap = (llc_snap_hdr_t *)skb_push(skb, 4);
+ snap->dsap = snap->ssap = 0xAA;
+ snap->ctrl = 0x03;
+ memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
+
+ /* Add AA-AA-03-00-00-00 */
+ snap = (llc_snap_hdr_t *)skb_push(skb, 10);
+ snap->dsap = snap->ssap = 0xAA;
+ snap->ctrl = 0x03;
+ memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
+
+ /* Add the VLAN specific information */
+ snap->protocol = htons(proto);
+ *(u16*)(snap + 1) = vlan_snap;
+
+ } else {
+ /* it's DIXII, time for some conversion */
+ unifi_trace(dev->priv, UDBG3, "DIXII len: %d\n", skb->len);
+
+ /* tack on SNAP */
+ snap = (llc_snap_hdr_t *)skb_push(skb, sizeof(llc_snap_hdr_t));
+ snap->dsap = snap->ssap = 0xAA;
+ snap->ctrl = 0x03;
+ /* Use the appropriate OUI. */
+ if ((proto == ETH_P_AARP) || (proto == ETH_P_IPX)) {
+ memcpy(snap->oui, oui_8021h, P80211_OUI_LEN);
+ } else {
+ memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
+ }
+ snap->protocol = htons(proto);
+ }
+
+ return 0;
+} /* skb_ether_to_80211() */
+
+
+static int
+indicate_amp_unidata(ul_client_t *client, uint16 proto, u8 *signal,
+ int signal_len, bulk_data_param_t *bulkdata)
+{
+ int filter_index;
+
+ for (filter_index = 0; filter_index < client->snap_filter.count; filter_index++) {
+ if (proto == client->snap_filter.protocols[filter_index]) {
+ /* Send to client */
+ client->event_hook(client,
+ signal, signal_len,
+ bulkdata, UDI_TO_HOST);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * skb_80211_to_ether
+ *
+ * Make sure the received frame is in Ethernet (802.3) form.
+ * De-encapsulates SNAP if necessary, adds a ethernet header.
+ *
+ * Arguments:
+ * payload Pointer to packet data received from UniFi.
+ * payload_length Number of bytes of data received from UniFi.
+ * daddr Destination MAC address.
+ * saddr Source MAC address.
+ *
+ * Returns:
+ * 0 on success, -1 if the packet is bad and should be dropped,
+ * 1 if the packet was forwarded to the SME or AMP client.
+ * ---------------------------------------------------------------------------
+ */
+static int
+skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb,
+ const unsigned char *daddr, const unsigned char *saddr,
+ u8 *packed_signal, int signal_len,
+ CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
+{
+ unsigned char *payload;
+ int payload_length;
+ struct ethhdr *eth;
+ llc_snap_hdr_t *snap;
+#define UF_VLAN_LLC_HEADER_SIZE 18
+ static const u8 vlan_inner_snap[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };
+
+ payload = skb->data;
+ payload_length = skb->len;
+
+ snap = (llc_snap_hdr_t *)payload;
+ eth = (struct ethhdr *)payload;
+
+ /*
+ * Test for the various encodings
+ */
+ if ((payload_length >= sizeof(llc_snap_hdr_t)) &&
+ (snap->dsap == 0xAA) &&
+ (snap->ssap == 0xAA) &&
+ (snap->ctrl == 0x03) &&
+ (snap->oui[0] == 0) &&
+ (snap->oui[1] == 0) &&
+ ((snap->oui[2] == 0) || (snap->oui[2] == 0xF8)))
+ {
+ /* AppleTalk AARP (2) or IPX SNAP */
+ if ((snap->oui[2] == 0) &&
+ ((ntohs(snap->protocol) == ETH_P_AARP) || (ntohs(snap->protocol) == ETH_P_IPX)))
+ {
+ u16 len;
+
+ unifi_trace(priv, UDBG3, "%s len: %d\n",
+ (ntohs(snap->protocol) == ETH_P_AARP) ? "ETH_P_AARP" : "ETH_P_IPX",
+ payload_length);
+ /* Add 802.3 header and leave full payload */
+ len = htons(skb->len);
+ memcpy(skb_push(skb, 2), &len, 2);
+ memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
+ memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
+
+ return 0;
+ }
+ /* VLAN-tagged IP */
+ if ((snap->oui[2] == 0) && (ntohs(snap->protocol) == ETH_P_8021Q))
+ {
+ /*
+ * The translation doesn't change the packet length, so is done in-place.
+ *
+ * Example header (from Std 802.11-2007 Annex M):
+ * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06
+ * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2
+ * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2
+ * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06
+ */
+ u16 vlan_snap;
+
+ if (payload_length < UF_VLAN_LLC_HEADER_SIZE) {
+ unifi_warning(priv, "VLAN SNAP header too short: %d bytes\n", payload_length);
+ return -1;
+ }
+
+ if (memcmp(payload + 10, vlan_inner_snap, 6)) {
+ unifi_warning(priv, "VLAN malformatted SNAP header.\n");
+ return -1;
+ }
+
+ unifi_trace(priv, UDBG3, "VLAN SNAP: %02x-%02x\n", payload[8], payload[9]);
+ unifi_trace(priv, UDBG3, "VLAN len: %d\n", payload_length);
+
+ /* Create the 802.3 header */
+
+ vlan_snap = *((u16*)(payload + 8));
+
+ /* Create LLC header without byte-swapping */
+ eth->h_proto = snap->protocol;
+
+ memcpy(eth->h_dest, daddr, ETH_ALEN);
+ memcpy(eth->h_source, saddr, ETH_ALEN);
+ *(u16*)(eth + 1) = vlan_snap;
+ return 0;
+ }
+
+ /* it's a SNAP + RFC1042 frame */
+ unifi_trace(priv, UDBG3, "SNAP+RFC1042 len: %d\n", payload_length);
+
+ /* chop SNAP+llc header from skb. */
+ skb_pull(skb, sizeof(llc_snap_hdr_t));
+
+ /* create 802.3 header at beginning of skb. */
+ eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
+ memcpy(eth->h_dest, daddr, ETH_ALEN);
+ memcpy(eth->h_source, saddr, ETH_ALEN);
+ /* Copy protocol field without byte-swapping */
+ eth->h_proto = snap->protocol;
+ } else {
+ static const u8 bt_oui[] = {0x00, 0x19, 0x58};
+ int indicated;
+
+ if (!memcmp(snap->oui, bt_oui, 3)) {
+
+ indicated = 0;
+ if (priv->amp_client) {
+ indicated = indicate_amp_unidata(priv->amp_client,
+ ntohs(snap->protocol),
+ packed_signal,
+ signal_len,
+ bulkdata);
+ }
+
+ if (!indicated && priv->sme_cli) {
+ indicate_amp_unidata(priv->sme_cli,
+ ntohs(snap->protocol),
+ packed_signal,
+ signal_len,
+ bulkdata);
+ }
+
+ unifi_net_data_free(priv, &bulkdata->d[0]);
+
+ return 1;
+ } else {
+ u16 len;
+
+ /* Add 802.3 header and leave full payload */
+ len = htons(skb->len);
+ memcpy(skb_push(skb, 2), &len, 2);
+ memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
+ memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
+ }
+ }
+
+ return 0;
+} /* skb_80211_to_ether() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * send_ma_unidata_request
+ * send_mlme_eapol_request
+ *
+ * These functions send a data packet to UniFi for transmission.
+ * EAP protocol packets are sent using send_mlme_eapol_request(),
+ * all other packets are sent using send_ma_unidata_request().
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * skb Socket buffer containing data packet to transmit
+ * ehdr Pointer to Ethernet header within skb.
+ *
+ * Returns:
+ * Zero on success or error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+send_ma_unidata_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr)
+{
+ CSR_SIGNAL signal;
+ CSR_MA_UNITDATA_REQUEST *req = &signal.u.MaUnitdataRequest;
+ bulk_data_param_t bulkdata;
+ int r;
+ const int proto = ntohs(ehdr->h_proto);
+ static unsigned long tag = 1;
+
+ /*
+ * Priority and ServiceClass are QoS items.
+ * If the packet is not unicast we send it as non-QoS.
+ */
+ if (((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 0) ||
+ ((ehdr->h_dest[0] & 0x01) == 0x01)) {
+ req->Priority = CSR_CONTENTION;
+ req->ServiceClass = CSR_REORDERABLE_MULTICAST;
+ }
+ else {
+ req->Priority = skb->priority >> 5;
+
+ if (req->Priority == 0) {
+ switch (proto) {
+ case 0x0800: /* IPv4 */
+ case 0x814C: /* SNMP */
+ case 0x880C: /* GSMP */
+ req->Priority = (CSR_PRIORITY) (skb->data[1] >> 5);
+ break;
+
+ case 0x8100: /* VLAN */
+ req->Priority = (CSR_PRIORITY) (skb->data[0] >> 5);
+ break;
+
+ case 0x86DD: /* IPv6 */
+ req->Priority = (CSR_PRIORITY) ((skb->data[0] & 0x0E) >> 1);
+ break;
+
+ default:
+ req->Priority = 0;
+ break;
+ }
+ }
+ req->ServiceClass = CSR_QOS_ACK;
+ }
+
+ /* Remove the ethernet header and add a SNAP header if necessary */
+ if (skb_ether_to_80211(priv->netdev, skb, proto) != 0) {
+ /* convert failed */
+ unifi_error(priv, "ether_to_80211 failed.\n");
+ return 1;
+ }
+ unifi_trace(priv, UDBG3, "Tx Frame with Priority: %d\n", req->Priority);
+
+#if 0
+ printk("after SNAP hdr:\n");
+ dump(skb->data, (skb->len > 32) ? 32 : skb->len);
+#endif
+
+ memcpy(req->Da.x, ehdr->h_dest, ETH_ALEN);
+ memcpy(req->Sa.x, ehdr->h_source, ETH_ALEN);
+
+#if 0
+ printk("MA-UNITDATA.req: %d bytes\n", skb->len);
+ printk(" Da %02X:%02X:%02X:%02X:%02X:%02X, Sa %02X:%02X:%02X:%02X:%02X:%02X\n",
+ req.Da.x[0], req.Da.x[1], req.Da.x[2],
+ req.Da.x[3], req.Da.x[4], req.Da.x[5],
+ req.Sa.x[0], req.Sa.x[1], req.Sa.x[2],
+ req.Sa.x[3], req.Sa.x[4], req.Sa.x[5]);
+#endif
+
+ req->RoutingInformation = CSR_NULL_RT; /* always set to zero */
+
+ req->HostTag = tag++;
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MA_UNITDATA_REQUEST_ID;
+ bulkdata.d[0].os_data_ptr = skb->data;
+ bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
+ bulkdata.d[0].data_length = skb->len;
+ bulkdata.d[1].os_data_ptr = NULL;
+ bulkdata.d[1].os_net_buf_ptr = NULL;
+ bulkdata.d[1].data_length = 0;
+
+#ifdef CSR_SUPPORT_SME
+ /* Notify the TA module for the Tx frame */
+ unifi_ta_sample(priv->card, unifi_traffic_tx,
+ &bulkdata.d[0], ehdr->h_source,
+ priv->netdev->dev_addr,
+ jiffies_to_msecs(jiffies));
+#endif /* CSR_SUPPORT_SME */
+
+ /* Send UniFi msg */
+ r = unifi_ma_unitdata(priv, priv->netdev_client, &signal, &bulkdata);
+ unifi_trace(priv, UDBG3, "UNITDATA result code = %d\n", r);
+
+ return r;
+} /* send_ma_unidata_request() */
+
+
+static int
+send_mlme_eapol_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_EAPOL_REQUEST *req = &signal.u.MlmeEapolRequest;
+ bulk_data_param_t bulkdata;
+ int r;
+ int proto = ntohs(ehdr->h_proto);
+
+ /* Remove the ethernet header and add a SNAP header if necessary */
+ if (skb_ether_to_80211(priv->netdev, skb, proto) != 0) {
+ /* convert failed */
+ unifi_error(priv, "ether_to_80211 failed.\n");
+ return 1;
+ }
+
+#if 0
+ printk("after SNAP hdr:\n");
+ dump(skb->data, (skb->len > 32) ? 32 : skb->len);
+#endif
+
+ memcpy(req->Da.x, &ehdr->h_dest, ETH_ALEN);
+ memcpy(req->Sa.x, &ehdr->h_source, ETH_ALEN);
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_EAPOL_REQUEST_ID;
+ bulkdata.d[0].os_data_ptr = skb->data;
+ bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
+ bulkdata.d[0].data_length = skb->len;
+ bulkdata.d[1].os_data_ptr = NULL;
+ bulkdata.d[1].os_net_buf_ptr = NULL;
+ bulkdata.d[1].data_length = 0;
+
+#ifdef CSR_SUPPORT_SME
+ /* Notify the TA module for the Tx frame */
+ unifi_ta_sample(priv->card, unifi_traffic_tx,
+ &bulkdata.d[0], ehdr->h_source,
+ priv->netdev->dev_addr,
+ jiffies_to_msecs(jiffies));
+#endif /* CSR_SUPPORT_SME */
+
+ /* Send to UniFi. This does not block for the reply. */
+ r = unifi_mlme_eapol(priv, priv->netdev_client, &signal, &bulkdata);
+ unifi_trace(priv, UDBG3, "EAPOL result code = %d\n", r);
+
+ return r;
+} /* send_mlme_eapol_request() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_net_xmit
+ *
+ * This function is called by the higher level stack to transmit an
+ * ethernet packet.
+ *
+ * Arguments:
+ * skb Ethernet packet to send.
+ * dev Pointer to the linux net device.
+ *
+ * Returns:
+ * Zero on success, non-zero if unable to transmit the packet.
+ *
+ * Notes:
+ * The controlled port is handled in the qdisc dequeue handler.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct ethhdr ehdr;
+ int proto;
+ int result;
+#ifndef CONFIG_NET_SCHED
+ unifi_PortAction cp_action;
+#endif /* CONFIG_NET_SCHED */
+
+ func_enter();
+
+#if 0
+ printk("xmit %d bytes\n", skb->len);
+ dump(skb->data, skb->len);
+#endif
+
+ /* Remove the ethernet header */
+ memcpy(&ehdr, skb->data, ETH_HLEN);
+ skb_pull(skb, ETH_HLEN);
+
+ proto = ntohs(ehdr.h_proto);
+
+#if 0
+ if (proto == ETH_P_PAE) {
+ printk("EAPOL, %d bytes\n", skb->len);
+ }
+#endif
+
+ if (proto == ETH_P_PAE) {
+ result = send_mlme_eapol_request(priv, skb, &ehdr);
+ } else {
+
+#ifdef CONFIG_NET_SCHED
+ /* Send the packet, port is open */
+ result = send_ma_unidata_request(priv, skb, &ehdr);
+#else
+ cp_action = verify_port(priv, ehdr.h_dest);
+
+ if (cp_action == unifi_8021x_PortOpen) {
+ result = send_ma_unidata_request(priv, skb, &ehdr);
+ } else {
+
+ /* Discard or block the packet if necessary */
+ if (cp_action == unifi_8021x_PortClosedBlock) {
+ /* We can not send the packet now, put it back to the queue */
+ unifi_trace(priv, UDBG5,
+ "unifi_net_xmit: packet requeued, controlled port blocked\n");
+ result = 1;
+ } else {
+ unifi_trace(priv, UDBG5,
+ "unifi_net_xmit: packet dropped, controlled port closed\n");
+ priv->stats.tx_dropped++;
+ kfree_skb(skb);
+
+ func_exit();
+ return 0;
+ }
+
+ }
+#endif /* CONFIG_NET_SCHED */
+
+ }
+
+ if (result == 0) {
+
+ dev->trans_start = jiffies;
+
+ /*
+ * Should really count tx stats in the UNITDATA.status signal but
+ * that doesn't have the length.
+ */
+ priv->stats.tx_packets++;
+ /* count only the packet payload */
+ priv->stats.tx_bytes += skb->len;
+
+ } else {
+ unifi_trace(priv, UDBG5, "Tx returns NETDEV_TX_BUSY\n");
+ result = 1; /* NETDEV_TX_BUSY */
+ }
+
+ /*
+ * Do not free the skb buffer, if the packet was delivered to the core
+ * it will be freed when it is send, otherwise the system will requeue it.
+ */
+
+ func_exit();
+ return result;
+} /* unifi_net_xmit() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_pause_xmit
+ * unifi_restart_xmit
+ *
+ * These functions are called from the UniFi core to control the flow
+ * of packets from the upper layers.
+ * unifi_pause_xmit() is called when the internal queue is full and
+ * should take action to stop unifi_ma_unitdata() being called.
+ * When the queue has drained, unifi_restart_xmit() will be called to
+ * re-enable the flow of packets for transmission.
+ *
+ * Arguments:
+ * ospriv OS private context pointer.
+ *
+ * Returns:
+ * unifi_pause_xmit() is called from interrupt context.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_pause_xmit(void *ospriv)
+{
+ unifi_priv_t *priv = ospriv;
+
+ unifi_trace(priv, UDBG2, "Stopping netif\n");
+ if (netif_running(priv->netdev)) {
+ UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev);
+ }
+} /* unifi_pause_xmit() */
+
+
+void
+unifi_restart_xmit(void *ospriv)
+{
+ unifi_priv_t *priv = ospriv;
+
+ unifi_trace(priv, UDBG2, "Waking netif\n");
+ if (netif_running(priv->netdev)) {
+ UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev);
+ }
+} /* unifi_restart_xmit() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_resume_xmit
+ *
+ * Is called when the controlled port is set to open,
+ * to notify the network stuck to schedule for transmission
+ * any packets queued in the qdisk while port was closed.
+ *
+ * Arguments:
+ * priv Pointer to device private struct
+ *
+ * Returns:
+ * ---------------------------------------------------------------------------
+ */
+void
+uf_resume_xmit(unifi_priv_t *priv)
+{
+ unifi_trace(priv, UDBG2, "Resuming netif\n");
+
+#ifdef CONFIG_NET_SCHED
+ if (netif_running(priv->netdev)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ netif_schedule_queue(netdev_get_tx_queue(priv->netdev, 0));
+#else
+ netif_schedule(priv->netdev);
+#endif /* LINUX_VERSION_CODE */
+ }
+#endif
+
+} /* uf_resume_xmit() */
+
+
+static unifi_PortAction verify_port(unifi_priv_t *priv, unsigned char *address)
+{
+#ifdef CSR_NATIVE_LINUX
+ return priv->wext_conf.block_controlled_port;
+#else
+ return uf_sme_controlled_port_state(priv, address);
+#endif
+}
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_rx
+ *
+ * Reformat a UniFi data received packet into a p80211 packet and
+ * pass it up the protocol stack.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+unifi_rx(unifi_priv_t *priv, u8 *packed_signal, int signal_len,
+ CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
+{
+ struct net_device *dev = priv->netdev;
+ const CSR_MA_UNITDATA_INDICATION *ind = &signal->u.MaUnitdataIndication;
+ struct sk_buff *skb;
+ struct ethhdr *eth;
+ unifi_PortAction controlled_port;
+ int r;
+
+ func_enter();
+
+ if (bulkdata->d[0].data_length == 0) {
+ unifi_warning(priv, "rx: MA-UNITDATA indication with zero bulk data\n");
+ func_exit();
+ return;
+ }
+
+#ifdef CSR_SUPPORT_SME
+ /* Notify the TA module for the Rx frame */
+ unifi_ta_sample(priv->card, unifi_traffic_rx,
+ &bulkdata->d[0],
+ ind->Sa.x,
+ priv->netdev->dev_addr,
+ jiffies_to_msecs(jiffies));
+#endif /* CSR_SUPPORT_SME */
+
+ skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
+ skb->len = bulkdata->d[0].data_length;
+
+ /*
+ * De-encapsulate any SNAP header and
+ * prepend an ethernet header so that the skb manipulation and ARP
+ * stuff works.
+ */
+ r = skb_80211_to_ether(priv, skb, ind->Da.x, ind->Sa.x,
+ packed_signal, signal_len,
+ signal, bulkdata);
+ if (r)
+ {
+ if (r == -1) {
+ /* Drop the packet and return */
+ priv->stats.rx_errors++;
+ priv->stats.rx_frame_errors++;
+ unifi_net_data_free(priv, &bulkdata->d[0]);
+ unifi_notice(priv, "unifi_rx: Discard unknown frame.\n");
+ }
+ return;
+ }
+
+ controlled_port = verify_port(priv, (unsigned char*)ind->Sa.x);
+
+ /* Now we look like a regular ethernet frame */
+
+ /* Apply 802.11X controlled port */
+ eth = (struct ethhdr *)skb->data;
+ if ((ntohs(eth->h_proto) != ETH_P_PAE) &&
+ (controlled_port != unifi_8021x_PortOpen)) {
+ /* Drop the packet and return */
+ priv->stats.rx_dropped++;
+ unifi_notice(priv, "unifi_rx: Dropping non-EAPOL packet, proto=0x%04x, port=%d\n",
+ ntohs(eth->h_proto), controlled_port);
+ unifi_net_data_free(priv, &bulkdata->d[0]);
+ return;
+ }
+
+
+ /* Test for an overlength frame */
+ if (skb->len > (dev->mtu + ETH_HLEN)) {
+ /* A bogus length ethfrm has been encap'd. */
+ /* Is someone trying an oflow attack? */
+ unifi_error(priv, "%s: oversize frame (%d > %d)\n",
+ dev->name,
+ skb->len, dev->mtu + ETH_HLEN);
+
+ /* Drop the packet and return */
+ priv->stats.rx_errors++;
+ priv->stats.rx_length_errors++;
+ unifi_net_data_free(priv, &bulkdata->d[0]);
+ return;
+ }
+
+
+ /* Fill in SKB meta data */
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+
+ /* Pass SKB up the stack */
+ netif_rx(skb);
+ dev->last_rx = jiffies;
+
+ /* Bump the rx stats */
+ priv->stats.rx_packets++;
+ priv->stats.rx_bytes += bulkdata->d[0].data_length;
+
+ func_exit();
+
+} /* unifi_rx() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_set_multicast_list
+ *
+ * This function is called by the higher level stack to set
+ * a list of multicast rx addresses.
+ *
+ * Arguments:
+ * dev Network Device pointer.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * ---------------------------------------------------------------------------
+ */
+
+static void
+unifi_set_multicast_list(struct net_device *dev)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct dev_mc_list *p; /* Pointer to the addresses structure. */
+ int i;
+ u8 *mc_list = priv->mc_list;
+
+ if (priv->init_progress != UNIFI_INIT_COMPLETED) {
+ return;
+ }
+
+ unifi_trace(priv, UDBG3,
+ "unifi_set_multicast_list (count=%d)\n", dev->mc_count);
+
+ /* Not enough space? */
+ if (dev->mc_count > UNIFI_MAX_MULTICAST_ADDRESSES) {
+ return;
+ }
+
+ /* Store the list to be processed by the work item. */
+ priv->mc_list_count = dev->mc_count;
+ p = dev->mc_list;
+ for (i = 0; i < dev->mc_count; i++) {
+ memcpy(mc_list, p->dmi_addr, ETH_ALEN);
+ p = p->next;
+ mc_list += ETH_ALEN;
+ }
+
+ /* Send a message to the workqueue */
+ queue_work(priv->unifi_workqueue, &priv->multicast_list_task);
+
+} /* unifi_set_multicast_list() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * netdev_mlme_event_handler
+ *
+ * Callback function to be used as the udi_event_callback when registering
+ * as a netdev client.
+ * To use it, a client specifies this function as the udi_event_callback
+ * to ul_register_client(). The signal dispatcher in
+ * unifi_receive_event() will call this function to deliver a signal.
+ *
+ * Arguments:
+ * pcli Pointer to the client instance.
+ * signal Pointer to the received signal.
+ * signal_len Size of the signal structure in bytes.
+ * bulkdata Pointer to structure containing any associated bulk data.
+ * dir Direction of the signal. Zero means from host,
+ * non-zero means to host.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+netdev_mlme_event_handler(ul_client_t *pcli,
+ u8 *sig_packed, int sig_len,
+ const bulk_data_param_t *bulkdata_o,
+ int dir)
+{
+ CSR_SIGNAL signal;
+ unifi_priv_t *priv = unifi_find_instance(pcli->instance);
+ int id, r;
+ bulk_data_param_t bulkdata;
+
+ func_enter();
+
+ /* Just a sanity check */
+ if (sig_packed == NULL) {
+ return;
+ }
+
+ /*
+ * This copy is to silence a compiler warning about discarding the
+ * const qualifier.
+ */
+ bulkdata = *bulkdata_o;
+
+ /* Get the unpacked signal */
+ r = read_unpack_signal(sig_packed, &signal);
+ if (r) {
+ unifi_error(priv, "Received unknown or corrupted signal.\n");
+ return;
+ }
+
+ id = signal.SignalPrimitiveHeader.SignalId;
+ unifi_trace(priv, UDBG3, "Netdev - Process signal 0x%X %s\n", id, lookup_signal_name(id));
+
+ /*
+ * Take the appropriate action for the signal.
+ */
+ switch (id) {
+ case CSR_MA_UNITDATA_INDICATION_ID:
+ unifi_rx(priv, sig_packed, sig_len, &signal, &bulkdata);
+ break;
+
+ case CSR_MA_UNITDATA_CONFIRM_ID:
+ unifi_ma_unitdata_status_ind(priv,
+ &signal.u.MaUnitdataConfirm);
+ break;
+
+ case CSR_DEBUG_STRING_INDICATION_ID:
+ debug_string_indication(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length);
+ break;
+
+ case CSR_DEBUG_WORD16_INDICATION_ID:
+ debug_word16_indication(priv, &signal);
+ break;
+
+ case CSR_DEBUG_GENERIC_CONFIRM_ID:
+ case CSR_DEBUG_GENERIC_INDICATION_ID:
+ debug_generic_indication(priv, &signal);
+ break;
+
+ default:
+ break;
+ }
+
+ func_exit();
+} /* netdev_mlme_event_handler() */
+
+
+
+#ifdef CONFIG_NET_SCHED
+/*
+ * ---------------------------------------------------------------------------
+ * uf_install_qdisc
+ *
+ * Creates a root qdisc, registers our qdisc handlers and
+ * overrides the device's qdisc_sleeping to prevent the system
+ * from creating a new one for our network device.
+ *
+ * Arguments:
+ * dev Pointer to the network device.
+ *
+ * Returns:
+ * 0 on success, Linux error code otherwise.
+ *
+ * Notes:
+ * This function holds the qdisk lock so it needs to be called
+ * after registering the network device in uf_register_netdev().
+ * Also, the qdisc_create_dflt() API has changed in 2.6.20 to
+ * include the parentid.
+ * ---------------------------------------------------------------------------
+ */
+int uf_install_qdisc(struct net_device *dev)
+{
+ struct Qdisc *qdisc;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ struct netdev_queue *queue0;
+#endif /* LINUX_VERSION_CODE */
+
+ qdisc = UF_QDISC_CREATE_DFLT(dev, &uf_qdisc_ops, TC_H_ROOT);
+ if (!qdisc) {
+ unifi_error(NULL, "%s: qdisc installation failed\n", dev->name);
+ return -EFAULT;
+ }
+
+ /*
+ * The following code is copied from the mac80211 code in the
+ * linux kernel. The usage of the handle is still not very clear.
+ */
+ qdisc->handle = 0x80020000;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ queue0 = netdev_get_tx_queue(dev, 0);
+ if (queue0 == NULL) {
+ unifi_error(NULL, "%s: netdev_get_tx_queue returned no queue\n", dev->name);
+ return -EFAULT;
+ }
+ queue0->qdisc = qdisc;
+ queue0->qdisc_sleeping = qdisc;
+#else
+ qdisc_lock_tree(dev);
+ list_add_tail(&qdisc->list, &dev->qdisc_list);
+ dev->qdisc_sleeping = qdisc;
+ qdisc_unlock_tree(dev);
+#endif
+
+ return 0;
+
+} /* uf_install_qdisc() */
+
+
+
+static int uf_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ unifi_priv_t *priv = qd->dev_queue->dev->priv;
+#else
+ unifi_priv_t *priv = qd->dev->priv;
+#endif /* LINUX_VERSION_CODE */
+ struct uf_sched_data *q = qdisc_priv(qd);
+ struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb;
+ struct ethhdr ehdr;
+ struct Qdisc *qdisc;
+ int r, queue, proto;
+
+ memcpy(&ehdr, skb->data, ETH_HLEN);
+ proto = ntohs(ehdr.h_proto);
+
+ /* 802.1x - apply controlled/uncontrolled port rules */
+ if (proto != ETH_P_PAE) {
+ queue = UF_QDISK_CONTROLLED_QUEUE;
+ } else {
+ queue = UF_QDISK_UNCONTROLLED_QUEUE;
+ }
+
+ pkt_data->queue = (unsigned int)queue;
+
+
+ qdisc = q->queues[queue];
+ r = qdisc->enqueue(skb, qdisc);
+ if (r == NET_XMIT_SUCCESS) {
+ qd->q.qlen++;
+ qd->bstats.bytes += skb->len;
+ qd->bstats.packets++;
+ return NET_XMIT_SUCCESS;
+ }
+
+ unifi_error(priv, "uf_qdiscop_enqueue: dropped\n");
+ qd->qstats.drops++;
+
+ return r;
+
+} /* uf_qdiscop_enqueue() */
+
+
+static int uf_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ unifi_priv_t *priv = qd->dev_queue->dev->priv;
+#else
+ unifi_priv_t *priv = qd->dev->priv;
+#endif /* LINUX_VERSION_CODE */
+ struct uf_sched_data *q = qdisc_priv(qd);
+ struct uf_tx_packet_data *pkt_data = (struct uf_tx_packet_data *) skb->cb;
+ struct Qdisc *qdisc;
+ int r;
+
+ unifi_trace(priv, UDBG5, "uf_qdiscop_requeue: (q=%d), tag=%u\n",
+ pkt_data->queue, pkt_data->host_tag);
+
+ /* we recorded which queue to use earlier! */
+ qdisc = q->queues[pkt_data->queue];
+
+ if ((r = qdisc->ops->requeue(skb, qdisc)) == 0) {
+ qd->q.qlen++;
+ return 0;
+ }
+
+ unifi_error(priv, "uf_qdiscop_requeue: dropped\n");
+ qd->qstats.drops++;
+
+ return r;
+} /* uf_qdiscop_requeue() */
+
+
+static struct sk_buff *uf_qdiscop_dequeue(struct Qdisc* qd)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ unifi_priv_t *priv = qd->dev_queue->dev->priv;
+#else
+ unifi_priv_t *priv = qd->dev->priv;
+#endif /* LINUX_VERSION_CODE */
+ struct uf_sched_data *q = qdisc_priv(qd);
+ struct sk_buff *skb;
+ struct Qdisc *qdisc;
+ int queue;
+ struct ethhdr ehdr;
+ struct uf_tx_packet_data *pkt_data;
+ unifi_PortAction cp_action;
+
+ /* check all the queues */
+ for (queue = 0; queue < UF_QDISK_MAX_QUEUES; queue++) {
+
+ qdisc = q->queues[queue];
+ skb = qdisc->dequeue(qdisc);
+ if (skb) {
+ /* A packet has been dequeued, decrease the queued packets count */
+ qd->q.qlen--;
+
+ pkt_data = (struct uf_tx_packet_data *) skb->cb;
+
+ /* The controlled port queue requires special handling */
+ if (queue == UF_QDISK_CONTROLLED_QUEUE) {
+ /* Check the controlled port status */
+ memcpy(&ehdr, skb->data, ETH_HLEN);
+ cp_action = verify_port(priv, ehdr.h_dest);
+
+ /* Discard or block the packet if necessary */
+ if (cp_action == unifi_8021x_PortClosedDiscard) {
+ unifi_trace(priv, UDBG5, "uf_qdiscop_dequeue: drop (q=%d), tag=%u\n",
+ pkt_data->queue, pkt_data->host_tag);
+ kfree_skb(skb);
+ break;
+ }
+
+ if (cp_action == unifi_8021x_PortClosedBlock) {
+ /* We can not send the packet now, put it back to the queue */
+ if (qdisc->ops->requeue(skb, qdisc) != 0) {
+ unifi_error(priv, "uf_qdiscop_dequeue: requeue (q=%d) failed, tag=%u, drop it\n",
+ pkt_data->queue, pkt_data->host_tag);
+
+ /* Requeue failed, drop the packet */
+ kfree_skb(skb);
+ break;
+ }
+ /* We requeued the packet, increase the queued packets count */
+ qd->q.qlen++;
+
+ unifi_trace(priv, UDBG5, "uf_qdiscop_dequeue: skip (q=%d), tag=%u\n",
+ pkt_data->queue, pkt_data->host_tag);
+ continue;
+ }
+ }
+
+ unifi_trace(priv, UDBG5, "uf_qdiscop_dequeue: new (q=%d), tag=%u\n",
+ pkt_data->queue, pkt_data->host_tag);
+
+ return skb;
+ }
+ }
+
+ return NULL;
+} /* uf_qdiscop_dequeue() */
+
+
+static void uf_qdiscop_reset(struct Qdisc* qd)
+{
+ struct uf_sched_data *q = qdisc_priv(qd);
+ int queue;
+
+ func_enter();
+
+ for (queue = 0; queue < UF_QDISK_MAX_QUEUES; queue++) {
+ qdisc_reset(q->queues[queue]);
+ }
+ qd->q.qlen = 0;
+
+ func_exit();
+} /* uf_qdiscop_reset() */
+
+
+static void uf_qdiscop_destroy(struct Qdisc* qd)
+{
+ struct uf_sched_data *q = qdisc_priv(qd);
+ int queue;
+
+ func_enter();
+
+ for (queue=0; queue < UF_QDISK_MAX_QUEUES; queue++) {
+ qdisc_destroy(q->queues[queue]);
+ q->queues[queue] = &noop_qdisc;
+ }
+
+ func_exit();
+} /* uf_qdiscop_destroy() */
+
+
+/* called whenever parameters are updated on existing qdisc */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+static int uf_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt)
+#else
+static int uf_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt)
+#endif
+{
+ return 0;
+} /* uf_qdiscop_tune() */
+
+
+/* called during initial creation of qdisc on device */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+static int uf_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
+#else
+static int uf_qdiscop_init(struct Qdisc *qd, struct rtattr *opt)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ struct net_device *dev = qd->dev_queue->dev;
+ unifi_priv_t *priv = dev->priv;
+#else
+ struct net_device *dev = qd->dev;
+ unifi_priv_t *priv = dev->priv;
+#endif /* LINUX_VERSION_CODE */
+ struct uf_sched_data *q = qdisc_priv(qd);
+ int err = 0, i;
+
+ /*
+ * check that there is no qdisc currently attached to device
+ * this ensures that we will be the root qdisc. (I can't find a better
+ * way to test this explicitly)
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+ if (dev->qdisc_sleeping != &noop_qdisc) {
+ return -EINVAL;
+ }
+#endif /* LINUX_VERSION_CODE */
+
+ /* make sure we do not mess with the ingress qdisc */
+ if (qd->flags & TCQ_F_INGRESS) {
+ return -EINVAL;
+ }
+
+ /* if options were passed in, set them */
+ if (opt) {
+ err = uf_qdiscop_tune(qd, opt);
+ }
+
+ /* create child queues */
+ for (i = 0; i < UF_QDISK_MAX_QUEUES; i++) {
+ q->queues[i] = UF_QDISC_CREATE_DFLT(dev, &pfifo_qdisc_ops,
+ qd->handle);
+ if (!q->queues[i]) {
+ q->queues[i] = &noop_qdisc;
+ unifi_error(priv, "%s child qdisc %i creation failed\n");
+ }
+ }
+
+ return err;
+} /* uf_qdiscop_init() */
+
+
+static int uf_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb)
+{
+ return skb->len;
+} /* uf_qdiscop_dump() */
+
+#endif /* CONFIG_NET_SCHED */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os.c
new file mode 100644
index 0000000..236b4ef
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os.c
@@ -0,0 +1,369 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: os.c
+ *
+ * PURPOSE:
+ * Routines to fulfil the OS-abstraction for the core driver.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include "driver/unifi.h"
+
+#include "unifi_priv.h"
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_malloc
+ * unifi_free
+ *
+ * General memory allocation and free.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void *
+unifi_malloc(void *ospriv, unsigned int size)
+{
+ UNUSED(ospriv);
+ return kmalloc(size, GFP_KERNEL);
+} /* unifi_malloc() */
+
+
+void
+unifi_free(void *ospriv, void *ptr)
+{
+ UNUSED(ospriv);
+ kfree(ptr);
+} /* unifi_free() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_net_data_malloc
+ *
+ * Allocate an OS specific net data buffer of "size" bytes.
+ * The bulk_data_slot.os_data_ptr must be initialised to point
+ * to the buffer allocated. The bulk_data_slot.length must be
+ * initialised to the requested size, zero otherwise.
+ * The bulk_data_slot.os_net_buf_ptr can be initialised to
+ * an OS specific pointer to be used in the unifi_net_data_free().
+ *
+ *
+ * Arguments:
+ * ospriv Pointer to device private context struct.
+ * bulk_data_slot Pointer to the bulk data structure to initialise.
+ * size Size of the buffer to be allocated.
+ *
+ * Returns:
+ * 0 on success, -1 otherwise.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_net_data_malloc(void *ospriv, bulk_data_desc_t *bulk_data_slot, unsigned int size)
+{
+ struct sk_buff *skb;
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+ int rounded_length;
+
+ if (priv->card_info.sdio_block_size == 0) {
+ unifi_error(priv, "unifi_net_data_malloc: Invalid SDIO block size\n");
+ return -1;
+ }
+
+ rounded_length = (size + priv->card_info.sdio_block_size - 1) & ~(priv->card_info.sdio_block_size - 1);
+
+ skb = dev_alloc_skb(rounded_length + 2 + ETH_HLEN);
+ if (! skb) {
+ unifi_error(ospriv, "alloc_skb failed.\n");
+ bulk_data_slot->os_net_buf_ptr = NULL;
+ bulk_data_slot->net_buf_length = 0;
+ bulk_data_slot->os_data_ptr = NULL;
+ bulk_data_slot->data_length = 0;
+ return -1;
+ }
+
+ bulk_data_slot->os_net_buf_ptr = (const unsigned char*)skb;
+ bulk_data_slot->net_buf_length = rounded_length + 2 + ETH_HLEN;
+ bulk_data_slot->os_data_ptr = (const void*)skb->data;
+ bulk_data_slot->data_length = size;
+
+ return 0;
+} /* unifi_net_data_malloc() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_net_data_free
+ *
+ * Free an OS specific net data buffer.
+ * The bulk_data_slot.length must be initialised to 0.
+ *
+ *
+ * Arguments:
+ * ospriv Pointer to device private context struct.
+ * bulk_data_slot Pointer to the bulk data structure that
+ * holds the data to be freed.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_net_data_free(void *ospriv, bulk_data_desc_t *bulk_data_slot)
+{
+ struct sk_buff *skb;
+ UNUSED(ospriv);
+
+ skb = (struct sk_buff *)bulk_data_slot->os_net_buf_ptr;
+ dev_kfree_skb(skb);
+
+ bulk_data_slot->net_buf_length = 0;
+ bulk_data_slot->data_length = 0;
+ bulk_data_slot->os_data_ptr = bulk_data_slot->os_net_buf_ptr = NULL;
+
+} /* unifi_net_data_free() */
+
+
+
+void
+unifi_delay_us(void *ospriv, unsigned long t)
+{
+ if (t > 1000) {
+ printk("WARNING: long busy wait: %ldus\n", t);
+ mdelay(t/1000);
+ } else {
+ udelay(t);
+ }
+} /* unifi_delay_us() */
+
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+/* Convenience function added in 2.6.14 */
+signed long
+schedule_timeout_interruptible(signed long timeout)
+{
+ set_current_state(TASK_INTERRUPTIBLE);
+ return schedule_timeout(timeout);
+}
+#endif
+
+unsigned long
+unifi_sleep_ms(void *ospriv, unsigned long t)
+{
+ unsigned long j;
+
+ /* Convert t in ms to jiffies and round up */
+ t = ((t * HZ) + 999) / 1000;
+ j = schedule_timeout_interruptible(t);
+
+ /* convert left over time in jiffies back to ms */
+ return (j * 1000) / HZ;
+} /* unifi_sleep_ms() */
+
+
+
+/* Module parameters */
+extern int unifi_debug;
+
+#ifdef UNIFI_DEBUG
+#define DEBUG_BUFFER_SIZE 80
+
+#define FORMAT_TRACE(_s, _len, _args, _fmt) \
+ do { \
+ va_start(_args, _fmt); \
+ _len += vsnprintf(&(_s)[_len], \
+ (DEBUG_BUFFER_SIZE - _len), \
+ _fmt, _args); \
+ va_end(_args); \
+ if (_len >= DEBUG_BUFFER_SIZE) { \
+ (_s)[DEBUG_BUFFER_SIZE - 2] = '\n'; \
+ (_s)[DEBUG_BUFFER_SIZE - 1] = 0; \
+ } \
+ } while (0)
+#endif /* UNIFI_DEBUG */
+
+void
+unifi_error(void* ospriv, const char *fmt, ...)
+{
+#ifdef UNIFI_DEBUG
+ unifi_priv_t *priv = (unifi_priv_t*) ospriv;
+ static char s[DEBUG_BUFFER_SIZE];
+ va_list args;
+ unsigned int len;
+
+ if (priv != NULL) {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance);
+ } else {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: ");
+ }
+
+ FORMAT_TRACE(s, len, args, fmt);
+
+ printk(s);
+#endif /* UNIFI_DEBUG */
+}
+
+void
+unifi_warning(void* ospriv, const char *fmt, ...)
+{
+#ifdef UNIFI_DEBUG
+ unifi_priv_t *priv = (unifi_priv_t*) ospriv;
+ static char s[DEBUG_BUFFER_SIZE];
+ va_list args;
+ unsigned int len;
+
+ if (priv != NULL) {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi%d: ", priv->instance);
+ } else {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi: ");
+ }
+
+ FORMAT_TRACE(s, len, args, fmt);
+
+ printk(s);
+#endif /* UNIFI_DEBUG */
+}
+
+
+void
+unifi_notice(void* ospriv, const char *fmt, ...)
+{
+#ifdef UNIFI_DEBUG
+ unifi_priv_t *priv = (unifi_priv_t*) ospriv;
+ static char s[DEBUG_BUFFER_SIZE];
+ va_list args;
+ unsigned int len;
+
+ if (priv != NULL) {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi%d: ", priv->instance);
+ } else {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi: ");
+ }
+
+ FORMAT_TRACE(s, len, args, fmt);
+
+ printk(s);
+#endif /* UNIFI_DEBUG */
+}
+
+
+void
+unifi_info(void* ospriv, const char *fmt, ...)
+{
+#ifdef UNIFI_DEBUG
+ unifi_priv_t *priv = (unifi_priv_t*) ospriv;
+ static char s[DEBUG_BUFFER_SIZE];
+ va_list args;
+ unsigned int len;
+
+ if (priv != NULL) {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi%d: ", priv->instance);
+ } else {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi: ");
+ }
+
+ FORMAT_TRACE(s, len, args, fmt);
+
+ printk(s);
+#endif /* UNIFI_DEBUG */
+}
+
+/* debugging */
+void
+unifi_trace(void* ospriv, int level, const char *fmt, ...)
+{
+#ifdef UNIFI_DEBUG
+ unifi_priv_t *priv = (unifi_priv_t*) ospriv;
+ static char s[DEBUG_BUFFER_SIZE];
+ va_list args;
+ unsigned int len;
+
+ if (unifi_debug >= level) {
+ if (priv != NULL) {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance);
+ } else {
+ len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: ");
+ }
+
+ FORMAT_TRACE(s, len, args, fmt);
+
+ printk(s);
+ }
+#endif /* UNIFI_DEBUG */
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Debugging support.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#ifdef UNIFI_DEBUG
+void
+dump(void *mem, int len)
+{
+ int i, col = 0;
+ unsigned char *pdata = (unsigned char *)mem;
+
+ for (i = 0; i < len; i++) {
+ if (col == 0) {
+ printk("0x%02X: ", i);
+ }
+
+ printk(" %02X", pdata[i]);
+
+ if (++col == 16) {
+ printk("\n");
+ col = 0;
+ }
+ }
+ if (col) {
+ printk("\n");
+ }
+} /* dump() */
+
+
+void
+dump16(void *mem, int len)
+{
+ int i, col=0;
+ unsigned short *p = (unsigned short *)mem;
+
+ for (i = 0; i < len; i+=2) {
+ if (col == 0) {
+ printk("0x%02X: ", i);
+ }
+
+ printk(" %04X", *p++);
+
+ if (++col == 8) {
+ printk("\n");
+ col = 0;
+ }
+ }
+ if (col) {
+ printk("\n");
+ }
+}
+#endif /* UNIFI_DEBUG */
+
+
+/* ---------------------------------------------------------------------------
+ * - End -
+ * ------------------------------------------------------------------------- */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os_version.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os_version.h
new file mode 100644
index 0000000..2e76194
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/os_version.h
@@ -0,0 +1,23 @@
+/*
+ * This file defines the version information for the portable UniFi driver.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ */
+#ifndef __OSVERSION_H__
+#define __OSVERSION_H__
+
+/*
+ * The version of the driver source code.
+ */
+#define UNIFI_DRIVER_VERSION "6.1"
+
+/*
+ * The version of the driver.
+ */
+#define UNIFI_DRIVER_BUILD_ID 147
+
+#endif /* __OSVERSION_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_support.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_support.h
new file mode 100644
index 0000000..7f5b8ca
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_support.h
@@ -0,0 +1,47 @@
+/** @file osa_support.h
+ *
+ * Operating System Abstraction support header file
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2006-2008. All rights reserved.
+ *
+ * @section DESCRIPTION
+ * Provides the hooks down into the target OS that are needed by the OS
+ * abstraction layer.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ ****************************************************************************/
+#ifndef OSA_SUPPORT_H
+#define OSA_SUPPORT_H
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+
+#undef osa_assert
+#define osa_assert
+
+#undef osa_malloc
+#undef osa_calloc
+#undef osa_free
+#undef osa_strtoul
+#undef osa_sprintf
+#define osa_malloc(sz) sme_osa_malloc(sz)
+#define osa_calloc(nmemb, sz) sme_osa_calloc(nmemb, sz)
+#define osa_free(ptr) sme_osa_free(ptr)
+#define osa_strtoul(nptr, endptr, base) simple_strtoul(nptr, endptr, base)
+#define osa_sprintf sprintf
+
+void *sme_osa_malloc(unsigned int sz);
+void sme_osa_free(void *ptr);
+void *sme_osa_calloc(unsigned int nmemb, unsigned int sz);
+
+#endif /* OSA_SUPPORT_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_types.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_types.h
new file mode 100644
index 0000000..348ba3a
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/osa_types.h
@@ -0,0 +1,149 @@
+/** @file osa_types.h
+ *
+ * Operating System C-Types definition header file
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2006-2008. All rights reserved.
+ *
+ * @section DESCRIPTION
+ * Provides definitions of common types such as uint16, uint32, Boolean, etc
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ ****************************************************************************/
+#ifndef OSA_TYPES_H
+# define OSA_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @{
+ * @ingroup abstractions
+ */
+
+/* STANDARD INCLUDES ********************************************************/
+#ifdef __KERNEL__
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#endif
+/* PROJECT INCLUDES *********************************************************/
+//#include "osa_support.h"
+#include "driver/unifi_types.h"
+/* PUBLIC MACROS ************************************************************/
+
+/**
+ * This macro allows a function to be declared as non-returning where supported
+ * by the compiler and appropriate for the target.
+ */
+//#ifdef __GNUC__
+//# define OSA_NORETURN __attribute__ ((__noreturn__))
+//#else
+# define OSA_NORETURN
+//#endif /* __GNUC__ */
+
+
+#if 0
+/** int8 definition */
+typedef signed char int8;
+
+/** int16 definition */
+typedef signed short int16;
+/** int32 definition */
+typedef signed long int32;
+
+/** uint8 definition */
+typedef unsigned char uint8;
+/** uint16 definition */
+typedef unsigned short uint16;
+/** uint32 definition */
+typedef unsigned long uint32;
+
+/* Types 64 bit types can be very platform specific */
+#ifdef SME_64BIT_INTRINSIC
+/** int64 definition */
+typedef long long int64;
+/** uint64 definition */
+typedef unsigned long long uint64;
+#else
+/** int64 definition */
+typedef struct int64
+{
+ /** int64 - part a int32 definition */
+ int32 a;
+ /** int64 - part b int32 definition */
+ int32 b;
+} int64;
+/** uint64 definition */
+typedef struct uint64
+{
+ /** uint64 - part b int32 definition */
+ uint32 a;
+ /** uint64 - part b int32 definition */
+ uint32 b;
+} uint64;
+#endif
+
+/** Boolean definition */
+typedef int16 Boolean;
+/** HAVE_BOOLEAN_TYPE definition */
+#define HAVE_BOOLEAN_TYPE 1
+
+#endif /* 0 */
+
+#ifndef __cplusplus
+#ifdef __KERNEL__
+/** bool definition */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+typedef int16 bool; /* only used by SDL */
+#endif
+#endif
+#endif
+
+/* Boolean values (never test for equality with TRUE) */
+#ifndef FALSE
+/** FALSE */
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+/** TRUE */
+#define TRUE 1
+#endif
+
+
+/* Null pointer (also in <stddef.h>, <stdio.h>, <stdlib.h> and <string.h>) */
+#ifndef NULL
+/** NULL */
+#define NULL ((void*)0)
+#endif
+
+/* Inlined minimum, maximum and absolute (may evaluate expressions twice) */
+#ifndef MAX
+/** MAX */
+#define MAX(a,b) (((a) < (b)) ? (b) : (a))
+#endif
+
+#ifndef MIN
+/** MIN */
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef ABS
+/** ABS */
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* OSA_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/putest.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/putest.c
new file mode 100644
index 0000000..7a09163
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/putest.c
@@ -0,0 +1,286 @@
+/*
+ * ***************************************************************************
+ * FILE: putest.c
+ *
+ * PURPOSE: putest related functions.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+
+#include "unifi_priv.h"
+
+
+int unifi_putest_cmd52_read(unifi_priv_t *priv, unsigned char *arg)
+{
+ struct unifi_putest_cmd52 cmd52_params;
+ uint8 *arg_pos;
+ unsigned int cmd_param_size;
+ int r;
+ unsigned char ret_buffer[32];
+ uint8 *ret_buffer_pos;
+
+ arg_pos = (uint8*)(((unifi_putest_command_t*)arg) + 1);
+ if (get_user(cmd_param_size, (int*)arg_pos)) {
+ unifi_error(priv,
+ "unifi_putest_cmd52_read: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) {
+ unifi_error(priv,
+ "unifi_putest_cmd52_read: cmd52 struct mismatch\n");
+ return -EINVAL;
+ }
+
+ arg_pos += sizeof(unsigned int);
+ if (copy_from_user(&cmd52_params,
+ (void*)arg_pos,
+ sizeof(struct unifi_putest_cmd52))) {
+ unifi_error(priv,
+ "unifi_putest_cmd52_read: Failed to get the cmd52 params\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG2, "cmd52r: func=%d addr=0x%x ",
+ cmd52_params.funcnum, cmd52_params.addr);
+
+ r = unifi_sdio_readb(priv->sdio, cmd52_params.funcnum,
+ cmd52_params.addr, &cmd52_params.data);
+ if (r)
+ {
+ unifi_error(priv,
+ "\nunifi_putest_cmd52_read: unifi_sdio_readb() failed (r=0x%x)\n", r);
+ return r;
+ }
+ unifi_trace(priv, UDBG2, "data=%d\n", cmd52_params.data);
+
+ /* Copy the info to the out buffer */
+ *(unifi_putest_command_t*)ret_buffer = UNIFI_PUTEST_CMD52_READ;
+ ret_buffer_pos = (uint8*)(((unifi_putest_command_t*)ret_buffer) + 1);
+ *(unsigned int*)ret_buffer_pos = sizeof(struct unifi_putest_cmd52);
+ ret_buffer_pos += sizeof(unsigned int);
+ memcpy(ret_buffer_pos, &cmd52_params, sizeof(struct unifi_putest_cmd52));
+ ret_buffer_pos += sizeof(struct unifi_putest_cmd52);
+
+ r = copy_to_user((void*)arg,
+ ret_buffer,
+ ret_buffer_pos - ret_buffer);
+ if (r) {
+ unifi_error(priv,
+ "unifi_putest_cmd52_read: Failed to return the data\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+
+int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg)
+{
+ struct unifi_putest_cmd52 cmd52_params;
+ uint8 *arg_pos;
+ unsigned int cmd_param_size;
+ int r;
+
+ arg_pos = (uint8*)(((unifi_putest_command_t*)arg) + 1);
+ if (get_user(cmd_param_size, (int*)arg_pos)) {
+ unifi_error(priv,
+ "unifi_putest_cmd52_write: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) {
+ unifi_error(priv,
+ "unifi_putest_cmd52_write: cmd52 struct mismatch\n");
+ return -EINVAL;
+ }
+
+ arg_pos += sizeof(unsigned int);
+ if (copy_from_user(&cmd52_params,
+ (void*)(arg_pos),
+ sizeof(struct unifi_putest_cmd52))) {
+ unifi_error(priv,
+ "unifi_putest_cmd52_write: Failed to get the cmd52 params\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG2, "cmd52w: func=%d addr=0x%x data=%d\n",
+ cmd52_params.funcnum, cmd52_params.addr, cmd52_params.data);
+
+ r = unifi_sdio_writeb(priv->sdio, cmd52_params.funcnum,
+ cmd52_params.addr, cmd52_params.data);
+ if (r)
+ {
+ unifi_error(priv,
+ "unifi_putest_cmd52_write: unifi_sdio_writeb() failed (r=0x%x)\n", r);
+ }
+
+ return r;
+}
+
+
+int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg)
+{
+ int sdio_clock_speed;
+ int r;
+
+ if (get_user(sdio_clock_speed, (int*)(((unifi_putest_command_t*)arg) + 1))) {
+ unifi_error(priv,
+ "unifi_putest_set_sdio_clock: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed);
+
+ r = unifi_sdio_set_max_clock_speed(priv->sdio, sdio_clock_speed);
+ if (r != sdio_clock_speed)
+ {
+ unifi_error(priv,
+ "unifi_putest_set_sdio_clock: Set clock failed (r=0x%x)\n", r);
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg)
+{
+ int r;
+
+ /* Suspend the SME and UniFi */
+ r = sme_sys_suspend(priv);
+ if (r) {
+ unifi_error(priv,
+ "unifi_putest_start: failed to suspend UniFi\n");
+ return r;
+ }
+
+ /* Power on UniFi */
+ r = unifi_sdio_power_on(priv->sdio);
+ if (r < 0) {
+ unifi_error(priv,
+ "unifi_putest_start: failed to power on UniFi\n");
+ return r;
+ }
+
+ r = unifi_init(priv->card);
+ if (r && (r != 1)) {
+ unifi_error(priv,
+ "unifi_putest_start: failed to init UniFi\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg)
+{
+ int r;
+
+ /* Power off UniFi */
+ unifi_sdio_power_off(priv->sdio);
+
+ /* Resume the SME and UniFi */
+ r = sme_sys_resume(priv);
+ if (r) {
+ unifi_error(priv,
+ "unifi_putest_stop: failed to resume UniFi\n");
+ }
+
+ return r;
+}
+
+
+int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg)
+{
+#define UF_PUTEST_MAX_FW_FILE_NAME 16
+#define UNIFI_MAX_FW_PATH_LEN 32
+ unsigned int fw_name_length;
+ unsigned char fw_name[UF_PUTEST_MAX_FW_FILE_NAME];
+ unsigned char *name_buffer;
+ int postfix;
+ char fw_path[UNIFI_MAX_FW_PATH_LEN];
+ const struct firmware *fw_entry;
+ struct dlpriv temp_fw_sta;
+ int r;
+
+ /* Get the f/w file name length */
+ if (get_user(fw_name_length, (unsigned int*)(((unifi_putest_command_t*)arg) + 1))) {
+ unifi_error(priv,
+ "unifi_putest_dl_fw: Failed to get the length argument\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG2, "unifi_putest_dl_fw: file name size = %d\n", fw_name_length);
+
+ /* Sanity check for the f/w file name length */
+ if (fw_name_length > UF_PUTEST_MAX_FW_FILE_NAME) {
+ unifi_error(priv,
+ "unifi_putest_dl_fw: F/W file name is too long\n");
+ return -EINVAL;
+ }
+
+ /* Get the f/w file name */
+ name_buffer = ((unsigned char*)arg) + sizeof(unifi_putest_command_t) + sizeof(unsigned int);
+ if (copy_from_user(fw_name, (void*)name_buffer, fw_name_length)) {
+ unifi_error(priv, "unifi_putest_dl_fw: Failed to get the file name\n");
+ return -EFAULT;
+ }
+
+ /* Keep the existing f/w to a temp, we need to restore it later */
+ temp_fw_sta = priv->fw_sta;
+
+ /* Get the putest f/w */
+ postfix = priv->instance;
+ scnprintf(fw_path, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
+ postfix, fw_name);
+ r = request_firmware(&fw_entry, fw_path, priv->unifi_device);
+ if (r == 0) {
+ priv->fw_sta.dl_data = vmalloc(fw_entry->size);
+ if (priv->fw_sta.dl_data == NULL)
+ {
+ unifi_error(priv,
+ "Failed to allocate memory for firmware image\n");
+ goto restore_fw;
+ }
+
+ memcpy(priv->fw_sta.dl_data, fw_entry->data, fw_entry->size);
+ priv->fw_sta.dl_len = fw_entry->size;
+ release_firmware(fw_entry);
+ } else {
+ unifi_error(priv, "Firmware file not available\n");
+ return -EINVAL;
+ }
+
+ /* Download the f/w */
+ r = unifi_download(priv->card, 0x0c00);
+ if (r < 0) {
+ unifi_error(priv,
+ "unifi_putest_dl_fw: failed to download the f/w\n");
+ goto free_fw;
+ }
+
+ /* Free the putest f/w... */
+free_fw:
+ vfree(priv->fw_sta.dl_data);
+
+ /* ... and restore the original f/w */
+restore_fw:
+ priv->fw_sta = temp_fw_sta;
+
+ return r;
+}
+
+
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_emb.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_emb.c
new file mode 100644
index 0000000..a822743
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_emb.c
@@ -0,0 +1,541 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: sdio_emb.c
+ *
+ * PURPOSE: Driver instantiation and deletion for SDIO on Linux.
+ *
+ * This file brings together the SDIO bus interface, the UniFi
+ * driver core and the Linux net_device stack.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+#include <sdioemb/sdio_api.h>
+
+
+/* sdioemb driver uses POSIX error codes too */
+#define convert_sdio_error(_r) (_r)
+
+
+
+int
+unifi_sdio_readb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata)
+{
+ struct sdio_dev *fdev = sdio;
+ int err;
+ if (funcnum == 0) {
+ err = sdio_f0_read8(fdev, addr, pdata);
+ } else {
+ err = sdio_read8(fdev, addr, pdata);
+ }
+ return convert_sdio_error(err);
+} /* unifi_sdio_readb() */
+
+int
+unifi_sdio_writeb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char data)
+{
+ struct sdio_dev *fdev = sdio;
+ int err;
+ if (funcnum == 0) {
+ err = sdio_f0_write8(fdev, addr, data);
+ } else {
+ err = sdio_write8(fdev, addr, data);
+ }
+ return convert_sdio_error(err);
+} /* unifi_sdio_writeb() */
+
+
+int
+unifi_sdio_block_rw(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata, unsigned int count, int direction)
+{
+ struct sdio_dev *fdev = sdio;
+ int err;
+
+ if (direction) {
+ err = sdio_write(fdev, addr, pdata, count);
+ } else {
+ err = sdio_read(fdev, addr, pdata, count);
+ }
+ return convert_sdio_error(err);
+} /* unifi_sdio_block_rw() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_set_max_clock_speed
+ *
+ * Set the maximum SDIO bus clock speed to use.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * max_khz maximum clock speed in kHz
+ *
+ * Returns:
+ * Set clock speed in kHz; or a UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_set_max_clock_speed(void *sdio, int max_khz)
+{
+ struct sdio_dev *fdev = sdio;
+
+ if (max_khz <= 0 || max_khz > sdio_clock) {
+ max_khz = sdio_clock;
+ }
+ sdio_set_max_bus_freq(fdev, 1000 * max_khz);
+ return max_khz;
+} /* unifi_sdio_set_max_clock_speed() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_enable_interrupt
+ *
+ * Enable or disable the SDIO interrupt.
+ * The driver can be made more efficient by disabling the SDIO interrupt
+ * during processing.
+ * The SDIO interrupt can be disabled by modifying the SDIO_INT_ENABLE
+ * register in the Card Common Control Register block, but this requires
+ * two CMD52 operations. A better solution is to mask the interrupt at
+ * the host controller.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * enable If zero disable (or mask) the interrupt, otherwise
+ * enable (or unmask) it.
+ *
+ * Returns:
+ * Zero on success or a UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_enable_interrupt(void *sdio, int enable)
+{
+ struct sdio_dev *fdev = sdio;
+
+ if (enable) {
+ sdio_enable_interrupt(fdev);
+ } else {
+ sdio_disable_interrupt(fdev);
+ }
+ return 0;
+} /* unifi_sdio_enable_interrupt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_enable
+ *
+ * Enable i/o on this function.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_enable(void *sdio)
+{
+ struct sdio_dev *fdev = sdio;
+ int r;
+
+ /* Enable UniFi function (the 802.11 part). */
+ r = sdio_enable_function(fdev);
+ if (r) {
+ unifi_error(NULL, "Failed to enable SDIO function %d\n", fdev->function);
+ return convert_sdio_error(r);
+ }
+ return 0;
+} /* unifi_sdio_enable() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_disable
+ *
+ * Disable i/o on this function.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_disable(void *sdio)
+{
+ struct sdio_dev *fdev = sdio;
+ int r;
+
+ /* Disable UniFi function (the 802.11 part). */
+ r = sdio_disable_function(fdev);
+ if (r) {
+ unifi_error(NULL, "Failed to disable SDIO function %d\n", fdev->function);
+ return convert_sdio_error(r);
+ }
+ return 0;
+} /* unifi_sdio_disable() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_active
+ *
+ * No-op as the bus goes to an active state at the start of every
+ * command.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_sdio_active(void *sdio)
+{
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_idle
+ *
+ * Set the function as idle.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_sdio_idle(void *sdio)
+{
+ struct sdio_dev *fdev = sdio;
+
+ sdio_idle_function(fdev);
+} /* unifi_sdio_idle() */
+
+
+int unifi_sdio_power_on(void *sdio)
+{
+ struct sdio_dev *fdev = sdio;
+
+ sdio_power_on(fdev);
+ return 0;
+}
+
+void unifi_sdio_power_off(void *sdio)
+{
+ struct sdio_dev *fdev = sdio;
+
+ sdio_power_off(fdev);
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_hard_reset
+ *
+ * Hard Resets UniFi is possible.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * 1 if the SDIO driver is not capable of doing a hard reset.
+ * 0 if a hard reset was successfully performed.
+ * -EIO if an I/O error occured while re-initializing the
+ * card. This is a fatal, non-recoverable error.
+ * -ENODEV if the card is no longer present.
+ * ---------------------------------------------------------------------------
+ */
+int unifi_sdio_hard_reset(void *sdio)
+{
+ struct sdio_dev *fdev = sdio;
+ int r;
+
+ /* Hard reset can be disabled by a module parameter */
+ r = 1;
+ if (disable_hw_reset != 1) {
+ r = sdio_hard_reset(fdev);
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ /* Set the SDIO bus width after a hard reset */
+ if (buswidth == 1) {
+ unifi_info(NULL, "Setting SDIO bus width to 1\n");
+ sdio_set_bus_width(fdev, buswidth);
+ } else if (buswidth == 4) {
+ unifi_info(NULL, "Setting SDIO bus width to 4\n");
+ sdio_set_bus_width(fdev, buswidth);
+ }
+
+ return r;
+
+} /* unifi_sdio_hard_reset() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_get_info
+ *
+ * Return UniFi information read by the SDIO driver.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * param_type The enum value for the required information
+ * param_value Pointer to store the returned information
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_get_info(void *sdio, enum unifi_sdio_request param_type, unsigned int *param_value)
+{
+ struct sdio_dev *fdev = sdio;
+
+ switch (param_type) {
+ case UNIFI_SDIO_IO_BLOCK_SIZE:
+ *param_value = fdev->blocksize;
+ break;
+ case UNIFI_SDIO_VENDOR_ID:
+ *param_value = fdev->vendor_id;
+ break;
+ case UNIFI_SDIO_DEVICE_ID:
+ *param_value = fdev->device_id;
+ break;
+ case UNIFI_SDIO_FUNCTION_NUM:
+ *param_value = fdev->function;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+
+} /* unifi_sdio_get_info() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_int_handler
+ *
+ * Interrupt callback function for SDIO interrupts.
+ * This is called in kernel context (i.e. not interrupt context).
+ * We retrieve the unifi context pointer and call the main UniFi
+ * interrupt handler.
+ *
+ * Arguments:
+ * fdev SDIO context pointer
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+uf_sdio_int_handler(struct sdio_dev *fdev)
+{
+ unifi_priv_t *priv = fdev->drv_data;
+
+ unifi_sdio_interrupt_handler(priv->card);
+} /* uf_sdio_int_handler() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_probe
+ *
+ * Card insert callback.
+ *
+ * Arguments:
+ * fdev SDIO context pointer
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_probe(struct sdio_dev *fdev)
+{
+ unifi_info(NULL, "card inserted\n");
+
+ /* Always override default SDIO bus clock */
+ unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock);
+ sdio_set_max_bus_freq(fdev, 1000 * sdio_clock);
+
+ /* Register this device with the main UniFi driver */
+ fdev->drv_data = register_unifi_sdio(fdev, fdev->slot_id, fdev->os_device);
+
+ return fdev->drv_data ? 0 : -ENOMEM;
+} /* uf_sdio_probe() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_remove
+ *
+ * Card removal callback.
+ *
+ * Arguments:
+ * fdev SDIO device
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+static void
+uf_sdio_remove(struct sdio_dev *fdev)
+{
+ unifi_info(NULL, "card removed\n");
+
+ sdio_disable_interrupt(fdev);
+
+ /* Clean up the main UniFi driver */
+ unregister_unifi_sdio(fdev->slot_id);
+} /* uf_sdio_remove */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_suspend
+ *
+ * System suspend callback.
+ *
+ * Arguments:
+ * fdev SDIO device
+ *
+ * Returns:
+ *
+ * ---------------------------------------------------------------------------
+ */
+static void
+uf_sdio_suspend(struct sdio_dev *fdev)
+{
+ unifi_priv_t *priv = fdev->drv_data;
+
+ unifi_trace(NULL, UDBG3, "Suspending...\n");
+ /* Pass event to UniFi Driver. */
+ unifi_suspend(priv);
+
+} /* uf_sdio_suspend() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_resume
+ *
+ * System resume callback.
+ *
+ * Arguments:
+ * fdev SDIO device
+ *
+ * Returns:
+ *
+ * ---------------------------------------------------------------------------
+ */
+static void
+uf_sdio_resume(struct sdio_dev *fdev)
+{
+ unifi_priv_t *priv = fdev->drv_data;
+
+ unifi_trace(NULL, UDBG3, "Resuming...\n");
+ /* Pass event to UniFi Driver. */
+ unifi_resume(priv);
+} /* uf_sdio_resume() */
+
+
+static struct sdio_id_table unifi_ids[] = {
+ {
+ .vendor_id = SDIO_MANF_ID_CSR,
+ .device_id = SDIO_CARD_ID_UNIFI_1,
+ .function = SDIO_WLAN_FUNC_ID_UNIFI_1,
+ .interface = SDD_ANY_IFACE,
+ },
+ {
+ .vendor_id = SDIO_MANF_ID_CSR,
+ .device_id = SDIO_CARD_ID_UNIFI_2,
+ .function = SDIO_WLAN_FUNC_ID_UNIFI_2,
+ .interface = SDD_ANY_IFACE,
+ },
+ {
+ .vendor_id = SDIO_MANF_ID_CSR,
+ .device_id = SDIO_CARD_ID_UNIFI_3,
+ .function = SDIO_WLAN_FUNC_ID_UNIFI_3,
+ .interface = SDD_ANY_IFACE,
+ },
+ {
+ .vendor_id = SDIO_MANF_ID_CSR,
+ .device_id = SDIO_CARD_ID_UNIFI_4,
+ .function = SDIO_WLAN_FUNC_ID_UNIFI_4,
+ .interface = SDD_ANY_IFACE,
+ },
+ { 0 },
+};
+
+static struct sdio_func_driver unifi_driver = {
+ .name = "unifi",
+ .id_table = unifi_ids,
+
+ .probe = uf_sdio_probe,
+ .remove = uf_sdio_remove,
+ .card_int_handler = uf_sdio_int_handler,
+ .suspend = uf_sdio_suspend,
+ .resume = uf_sdio_resume,
+};
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_load
+ * uf_sdio_unload
+ *
+ * These functions are called from the main module load and unload
+ * functions. They perform the appropriate operations for the monolithic
+ * driver.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int __init
+uf_sdio_load(void)
+{
+ int r;
+
+ printk("Unifi: Using CSR embedded SDIO driver\n");
+
+ r = sdio_driver_register(&unifi_driver);
+ if (r) {
+ unifi_error(NULL, "Failed to register UniFi SDIO driver: %d\n", r);
+ return r;
+ }
+
+ return 0;
+} /* uf_sdio_load() */
+
+
+
+void __exit
+uf_sdio_unload(void)
+{
+ sdio_driver_unregister(&unifi_driver);
+} /* uf_sdio_unload() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Kbuild b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Kbuild
new file mode 100644
index 0000000..dae251e
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Kbuild
@@ -0,0 +1,24 @@
+# ----------------------------------------------------------------------------
+# FILE: Kbuild
+#
+# PURPOSE:
+# Build instructions for SDIO Glue Module.
+#
+#
+# Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+# ----------------------------------------------------------------------------
+
+# Read platform config details.
+DRIVERTOP := $(M)
+
+obj-m := fs_sdio.o
+
+
+fs_sdio-y := \
+ fs_lx.o
+
+
+U_INCLUDES = -I$(M)
+U_DEFINES = -DMODULE -D__KERNEL__
+
+EXTRA_CFLAGS += $(U_DEFINES) $(U_INCLUDES)
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Makefile b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Makefile
new file mode 100644
index 0000000..b1a66f5
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/Makefile
@@ -0,0 +1,27 @@
+ifeq ($(CONFIG),)
+$(error CONFIG not set)
+endif
+
+all: driver
+
+include config.$(CONFIG).mk
+
+DRIVERTOP := $(shell pwd)
+OSTOP := $(DRIVERTOP)
+
+BUILDDIR := $(DRIVERTOP)
+
+driver: buildtree modules
+
+tools: buildtree
+ $(MAKE) -C $(BUILDDIR)
+
+install: install_driver post_install_hook
+
+install_driver: driver install_modules
+
+clean: clean_modules
+
+buildtree: $(BUILDDIR)
+
+.PHONY: post_install_hook
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/build b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/build
new file mode 100755
index 0000000..823aa9b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/build
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+os_top=$(dirname $0)
+config=$1 ; shift
+config_file=$os_top/config.$config.mk
+
+if [ "x$config" = "x" ]; then
+ echo "Usage: $0 <config> [<make target/option>]..." >&2
+ exit 1
+fi
+
+if [ ! -e $config_file ]; then
+ echo "Configuration '$config' ($config_file) does not exist." >&2
+ exit 1
+fi
+
+exec make -C ${os_top} CONFIG=$config "$@"
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/config.generic.mk b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/config.generic.mk
new file mode 100644
index 0000000..e564a99
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/config.generic.mk
@@ -0,0 +1,25 @@
+KDIR ?= /lib/modules/$(shell uname -r)/build
+
+modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR) \
+ O=$(O) V=$(V)
+
+install_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR) modules_install INSTALL_MOD_PATH=$(DESTDIR) \
+ O=$(O) V=$(V)
+
+# Kbuild's clean target doesn't play nicely with our Kbuild file:
+# ../core/ isn't cleaned because it's above M; and .config isn't
+# included so SDIO_PLATFORM isn't defined.
+clean_modules:
+ $(MAKE) -C $(KDIR) M=$(BUILDDIR) clean \
+ O=$(O) V=$(V) SDIO_PLATFORM=unused
+
+ifneq ($(CROSS_COMPILE),)
+export CROSS_COMPILE
+endif
+
+ifneq ($(ARCH),)
+export ARCH
+endif
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_lx.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_lx.c
new file mode 100644
index 0000000..ea1c5ff
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_lx.c
@@ -0,0 +1,983 @@
+/*
+ * Freescale SDIO glue modules.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * Note:
+ * The Freescale MMC/SDIO driver is a project under development so the
+ * code that interfaces their driver is likely to have changed between
+ * releases. This code is tested only with the SDIO/MMC driver released
+ * by Freescale for the imx31ads board using Linux Kernel 2.6.16.
+ *
+ * Also, the code in the probe that sets the pull-ups is platform
+ * specific and should really be part of the controller's initialisation.
+ * In the aforesaid Freescale release this code was missing but may
+ * be in place in the future releases.
+ *
+ * Important:
+ * This module does not support more than one device driver instances.
+ *
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/scatterlist.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/protocol.h>
+#include <linux/mmc/host.h>
+
+#ifdef CONFIG_MX31_3STACK
+/* The 3STACK board allows control of the power supply and clock to
+ * the APM module
+ */
+#include <linux/clk.h>
+#include <asm/arch/pmic_power.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/gpio.h>
+#endif
+
+#include "fs_sdio_api.h"
+
+#define CMD_RETRIES 3
+
+#define SDIO_FBR_REG(f, r) (0x100*(f) + (r))
+#define SDIO_FBR_BLK_SIZE(f) SDIO_FBR_REG(f, 0x10)
+
+#define SDIO_CCCR_IO_EN 0x02
+#define SDIO_CCCR_IO_READY 0x03
+#define SDIO_CCCR_INT_EN 0x04
+#define SDIO_CCCR_INT_PENDING 0x05
+#define SDIO_CCCR_IO_ABORT 0x06
+#define SDIO_CCCR_BUS_IFACE_CNTL 0x07
+#define SDIO_CCCR_CIS_PTR 0x09
+#define SDIO_CCCR_FN0_BLK_SZ0 0x10
+#define SDIO_CCCR_FN0_BLK_SZ1 0x11
+
+#define SDIO_FBR_CIS_PTR 0x109
+
+#define CISTPL_MANFID 0x20
+#define CISTPL_MANFID_SIZE 0x04
+#define CISTPL_FUNCE 0x22
+#define CISTPL_FUNCE_01_SIZE 0x2a
+#define CISTPL_END 0xff
+
+static int fs_sdio_probe(struct mmc_card *card);
+static void fs_sdio_remove(struct mmc_card *card);
+static irqreturn_t fs_sdio_irq(int irq, void *devid);
+static int fs_sdio_suspend(struct mmc_card *card, pm_message_t state);
+static int fs_sdio_resume(struct mmc_card *card);
+
+
+EXPORT_SYMBOL(fs_sdio_register_driver);
+EXPORT_SYMBOL(fs_sdio_unregister_driver);
+
+EXPORT_SYMBOL(fs_sdio_readb);
+EXPORT_SYMBOL(fs_sdio_writeb);
+EXPORT_SYMBOL(fs_sdio_block_rw);
+EXPORT_SYMBOL(fs_sdio_set_block_size);
+EXPORT_SYMBOL(fs_sdio_set_max_clock_speed);
+EXPORT_SYMBOL(fs_sdio_enable);
+EXPORT_SYMBOL(fs_sdio_enable_interrupt);
+EXPORT_SYMBOL(fs_sdio_hard_reset);
+
+/* Globals to store the context to this module and the device driver */
+static struct sdio_dev *available_sdio_dev = NULL;
+static struct fs_driver *available_driver = NULL;
+
+
+
+enum sdio_cmd_direction {
+ CMD_READ, CMD_WRITE,
+};
+
+
+static int sdio_cmd52(struct mmc_card *card, int func, uint32_t addr, uint8_t *data,
+ enum sdio_cmd_direction dir)
+{
+ struct mmc_command cmd;
+ int err;
+ int rw, raw;
+
+ if (dir == CMD_READ) {
+ rw = SDIO_RW_READ;
+ raw = 0;
+ } else {
+ rw = SDIO_RW_WRITE;
+ raw = 1;
+ }
+
+ mmc_card_claim_host(card);
+ cmd.opcode = SD_IO_RW_DIRECT;
+ cmd.arg = IO_RW_DIRECT_ARG(rw, raw, func, addr, (rw == SDIO_RW_WRITE ? (*data) : 0));
+ cmd.flags = MMC_RSP_R5 | MMC_KEEP_CLK_RUN;
+ err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES);
+ mmc_card_release_host(card);
+
+ if (err) {
+ return -EINVAL;
+ }
+
+ if (rw == SDIO_RW_READ) {
+ *data = (cmd.resp[0] & 0xff);
+ }
+
+ return 0;
+}
+
+
+static int sdio_cmd53(struct sdio_dev *fdev, int func, uint32_t addr, uint8_t *data,
+ size_t len, enum sdio_cmd_direction dir)
+{
+ struct mmc_card *card = fdev->card;
+ struct mmc_request mmc_req;
+ struct mmc_command cmd;
+ struct mmc_data mdata;
+ struct scatterlist sg;
+
+ int err;
+ int rw;
+ int count;
+
+ /* Read or Write ? */
+ if (dir == CMD_WRITE) {
+ rw = SDIO_RW_WRITE;
+ } else {
+ rw = SDIO_RW_READ;
+ }
+
+ /* Calculate the request length */
+ if (len >= fdev->max_blocksize) {
+ count = len / fdev->max_blocksize;
+ } else {
+ count = len;
+ }
+
+ mmc_card_claim_host(card);
+ cmd.opcode = SD_IO_RW_EXTENDED; //CM53
+ cmd.arg = IO_RW_EXTENDED_ARG(rw,
+ len >= fdev->max_blocksize ? 1 : 0,
+ 0,
+ func, addr, count);
+ cmd.flags = MMC_RSP_R5 | MMC_RSP_BUSY | MMC_KEEP_CLK_RUN;
+
+ cmd.retries = 0;
+
+ mmc_req.cmd = &cmd;
+
+ mdata.timeout_ns = 80000000;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
+ mdata.blksz_bits = (len >= fdev->max_blocksize ? fdev->max_blocksize*8 : len*8);
+#endif
+ mdata.blksz = (len >= fdev->max_blocksize ? fdev->max_blocksize : len);
+ mdata.blocks = (len >= fdev->max_blocksize ? count : 1);
+
+ if (rw == SDIO_RW_WRITE) {
+ mdata.flags = MMC_DATA_WRITE;
+ } else {
+ mdata.flags = MMC_DATA_READ;
+ }
+
+ if ((len >= fdev->max_blocksize) && (count > 1)) {
+ mdata.flags |= MMC_DATA_MULTI;
+ }
+
+ /* Make a scatterlist from the buffer. */
+ sg_init_one(&sg, data, len);
+ mdata.sg = &sg;
+ mdata.sg_len = 1;
+
+ mdata.mrq = &mmc_req;
+ mdata.stop = NULL;
+ cmd.data = &mdata;
+ cmd.mrq = &mmc_req;
+
+ mmc_req.data = &mdata;
+ mmc_req.stop = NULL;
+
+ err = mmc_wait_for_req(card->host, &mmc_req);
+ mmc_card_release_host(card);
+
+ if (err || mdata.error) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+
+int
+fs_sdio_readb(struct sdio_dev *fdev, int funcnum, unsigned long addr,
+ unsigned char *pdata)
+{
+ struct mmc_card *card = fdev->card;
+
+ return sdio_cmd52(card, funcnum, addr, pdata, CMD_READ);
+}
+
+
+int
+fs_sdio_writeb(struct sdio_dev *fdev, int funcnum, unsigned long addr,
+ unsigned char data)
+{
+ struct mmc_card *card = fdev->card;
+
+ return sdio_cmd52(card, funcnum, addr, &data, CMD_WRITE);
+}
+
+
+int
+fs_sdio_block_rw(struct sdio_dev *fdev, int funcnum, unsigned long addr,
+ unsigned char *pdata, unsigned int count, int direction)
+{
+ int ret, remainder = 0;
+
+ if (count > fdev->max_blocksize) {
+ remainder = count % fdev->max_blocksize;
+ count -= remainder;
+ }
+
+ ret = sdio_cmd53(fdev, funcnum, addr, (uint8_t *)pdata, count, direction);
+ if (!ret && remainder) {
+ ret = sdio_cmd53(fdev, funcnum, addr, (uint8_t *)pdata + count, remainder, direction);
+ }
+
+ return ret;
+}
+
+
+int
+fs_sdio_enable_interrupt(struct sdio_dev *fdev, int enable)
+{
+ struct mmc_card *card = fdev->card;
+ unsigned flags;
+
+ spin_lock_irqsave(&fdev->lock, flags);
+ if (enable) {
+ if (!fdev->int_enabled) {
+ fdev->int_enabled = 1;
+ enable_irq(card->host->sdio_irq);
+ }
+ } else {
+ if (fdev->int_enabled) {
+ disable_irq_nosync(card->host->sdio_irq);
+ fdev->int_enabled = 0;
+ }
+ }
+ spin_unlock_irqrestore(&fdev->lock, flags);
+
+ return 0;
+}
+
+
+
+
+
+/**
+ * Read a 24 bit CIS pointer register.
+ */
+static int
+sdio_cis_read_ptr_reg(struct mmc_card *card, uint32_t addr, uint32_t *ptr)
+{
+ uint32_t cis_ptr = 0;
+ int b;
+
+ for (b = 0; b < 3; b++) {
+ uint8_t p;
+ int ret = sdio_cmd52(card, 0, addr + b, &p, CMD_READ);
+ if (ret < 0)
+ return ret;
+ cis_ptr |= p << (b * 8);
+ }
+ *ptr = cis_ptr;
+ return 0;
+}
+
+/**
+ * Read a CIS tuple.
+ */
+static int
+sdio_cis_get_tuple(struct mmc_card *card, uint32_t cis_ptr, uint8_t tuple,
+ void *buf, size_t len)
+{
+ uint8_t *bbuf = buf;
+ uint8_t tpl, lnk;
+
+ /* find tuple */
+ for(;;) {
+ int ret;
+
+ if (cis_ptr >= 0x17000) {
+ /* Valid CIS should have a CISTPL_END so this shouldn't happen. */
+ return -ENXIO;
+ }
+
+ ret = sdio_cmd52(card, 0, cis_ptr++, &tpl, CMD_READ);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sdio_cmd52(card, 0, cis_ptr++, &lnk, CMD_READ);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (tpl == CISTPL_END) {
+ return -ENXIO;
+ }
+ if (tpl == tuple) {
+ break;
+ }
+ cis_ptr += lnk;
+ }
+
+ if (lnk > len) {
+ return -EINVAL;
+ }
+
+ /* copy tuple data */
+ for (; lnk > 0; lnk--) {
+ int ret;
+
+ ret = sdio_cmd52(card, 0, cis_ptr++, bbuf++, CMD_READ);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+
+
+static int sdio_card_read_info(struct sdio_dev *fdev)
+{
+ struct mmc_card *card = fdev->card;
+ uint32_t cis_ptr;
+ uint16_t manfid[2];
+ uint8_t funce_dat[CISTPL_FUNCE_01_SIZE];
+ int ret;
+
+ /* read func CIS ptr */
+ if (sdio_cis_read_ptr_reg(card, SDIO_FBR_CIS_PTR, &cis_ptr) < 0) {
+ return -1;
+ }
+ if (cis_ptr < 0x1000 || cis_ptr > 0x17000) {
+ return -1;
+ }
+
+ if (sdio_cis_get_tuple(card, cis_ptr, CISTPL_FUNCE, funce_dat, CISTPL_FUNCE_01_SIZE) < 0) {
+ return -1;
+ }
+ fdev->max_blocksize = (funce_dat[0x0c] & 0xff) | ((funce_dat[0x0d] & 0xff) << 8);
+
+ /* Set the function 1 block size */
+ ret = fs_sdio_writeb(fdev, 0, SDIO_FBR_BLK_SIZE(1), fdev->max_blocksize & 0xFF);
+ if (ret) {
+ return ret;
+ }
+ ret = fs_sdio_writeb(fdev, 0, SDIO_FBR_BLK_SIZE(1)+1, (fdev->max_blocksize >> 8) & 0xFF);
+ if (ret) {
+ return ret;
+ }
+
+ /* Set the block size read from the device to the MMC driver. */
+ card->csd.read_blkbits = fdev->max_blocksize*8;
+ card->csd.write_blkbits = fdev->max_blocksize*8;
+
+
+ /* read common CIS ptr */
+ if (sdio_cis_read_ptr_reg(card, SDIO_CCCR_CIS_PTR, &cis_ptr) < 0) {
+ return -1;
+ }
+ if (cis_ptr < 0x1000 || cis_ptr > 0x17000) {
+ return -1;
+ }
+ /* read manfid from CIS */
+ if (sdio_cis_get_tuple(card, cis_ptr, CISTPL_MANFID, &manfid, CISTPL_MANFID_SIZE) < 0) {
+ return -1;
+ }
+ fdev->vendor_id = le16_to_cpu(manfid[0]);
+
+ /* read common CIS ptr */
+ if (sdio_cis_read_ptr_reg(card, SDIO_CCCR_CIS_PTR, &cis_ptr) < 0) {
+ return -1;
+ }
+ if (cis_ptr < 0x1000 || cis_ptr > 0x17000) {
+ return -1;
+ }
+ /* read manfid from CIS */
+ if (sdio_cis_get_tuple(card, cis_ptr, CISTPL_MANFID, &manfid, CISTPL_MANFID_SIZE) < 0) {
+ return -1;
+ }
+ fdev->device_id = le16_to_cpu(manfid[1]);
+
+ return 0;
+}
+
+static void fs_sdio_cmd0(struct mmc_card *card)
+{
+ struct mmc_command cmd;
+ int err;
+
+ mmc_card_claim_host(card);
+ cmd.opcode = MMC_GO_IDLE_STATE;
+ cmd.arg = 0;
+ cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
+ err = mmc_wait_for_cmd(card->host, &cmd, 0);
+ if( err )
+ {
+ printk("%s: error %d\n", __FUNCTION__, err );
+ }
+ mmc_card_release_host(card);
+}
+
+static void fs_sdio_cmd5(struct mmc_card *card, uint32_t arg)
+{
+ struct mmc_command cmd;
+ int i, err = 0;
+
+ mmc_card_claim_host(card);
+
+ cmd.opcode = SD_IO_SEND_OP_COND;
+ cmd.arg = arg;
+ cmd.flags = MMC_RSP_R4 | MMC_CMD_BCR;
+
+ for (i = 100; i; i--) {
+ err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES);
+ if (err != MMC_ERR_NONE)
+ {
+ printk("%s:%d: error %d\n", __FUNCTION__, __LINE__, err );
+ break;
+ }
+
+ if (cmd.resp[0] & MMC_CARD_BUSY || arg == 0)
+ {
+ break;
+ }
+
+ err = MMC_ERR_TIMEOUT;
+
+ mdelay(10);
+ }
+
+ mmc_card_release_host(card);
+}
+
+static void fs_sdio_cmd3(struct mmc_card *card)
+{
+ struct mmc_command cmd;
+ int err;
+
+ mmc_card_claim_host(card);
+ cmd.opcode = MMC_SET_RELATIVE_ADDR;
+ cmd.arg = 0;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES);
+ if( err )
+ {
+ printk("%s:%d: error %d\n", __FUNCTION__, __LINE__, err );
+ }
+
+ mmc_card_release_host(card);
+}
+
+static void fs_sdio_cmd7(struct mmc_card *card)
+{
+ struct mmc_command cmd;
+ int err;
+
+ mmc_card_claim_host(card);
+ cmd.opcode = MMC_SELECT_CARD;
+ cmd.arg = card->rca << 16;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES);
+ if( err )
+ {
+ printk("%s:%d: error %d\n", __FUNCTION__, __LINE__, err );
+ }
+ mmc_card_release_host(card);
+}
+
+#define IO_EN_TIMEOUT_MS 500
+
+int
+fs_sdio_enable(struct sdio_dev *fdev)
+{
+ uint8_t io_en, io_rdy;
+ int timeout;
+ int ret;
+
+ /* The card may be active if not following a hard reset - abort it first */
+ fs_sdio_writeb(fdev, 0, SDIO_CCCR_IO_ABORT, 0x8);
+
+ /* We must go though complete card init, as we have just reset it */
+ /* cmd0, then 2 x cmd5, cmd3 and finally 7 */
+
+ /* Do a few cmd0 to settle down */
+ for(timeout=0;timeout<2;timeout++)
+ {
+ fs_sdio_cmd0(fdev->card);
+ }
+ timeout = IO_EN_TIMEOUT_MS;
+
+ fs_sdio_cmd5(fdev->card, 0);
+ fs_sdio_cmd5(fdev->card, 0x80000);
+ fs_sdio_cmd3(fdev->card);
+ fs_sdio_cmd7(fdev->card);
+
+ ret = fs_sdio_writeb(fdev, 0, SDIO_CCCR_BUS_IFACE_CNTL, 0x22);
+ if (ret) {
+ printk("%s: err %d line %d\n", __FUNCTION__, ret, __LINE__ );
+ goto err;
+ }
+
+ ret = fs_sdio_writeb(fdev, 0, SDIO_CCCR_INT_EN, 3);
+ if (ret) {
+ printk("%s: err %d line %d\n", __FUNCTION__, ret, __LINE__ );
+ goto err;
+ }
+
+ /* Read-Modify-Write the I/O Enable for function 1. */
+ ret = fs_sdio_readb(fdev, 0, SDIO_CCCR_IO_EN, &io_en);
+ if (ret) {
+ printk("%s: err %d line %d\n", __FUNCTION__, ret, __LINE__ );
+ goto err;
+ }
+
+ io_en |= (1 << 1);
+ ret = fs_sdio_writeb(fdev, 0, SDIO_CCCR_IO_EN, io_en);
+ if (ret) {
+ printk("%s: err %d line %d\n", __FUNCTION__, ret, __LINE__ );
+ goto err;
+ }
+
+ /* Wait until the function is enabled. */
+ while (timeout) {
+ ret = fs_sdio_readb(fdev, 0, SDIO_CCCR_IO_READY, &io_rdy);
+ if (ret) {
+ printk("%s: err %d line %d\n", __FUNCTION__, ret, __LINE__ );
+ goto err;
+ }
+ if (io_rdy & (1 << 1)) {
+ break;
+ }
+
+ udelay(1);
+ timeout--;
+ }
+
+ if(! timeout )
+ {
+ ret = -ETIMEDOUT;
+ printk("%s: err %d line %d\n", __FUNCTION__, ret, __LINE__ );
+ goto err;
+ }
+
+ /* Set the function 1 block size */
+ ret = fs_sdio_writeb(fdev, 0, SDIO_FBR_BLK_SIZE(1), fdev->max_blocksize & 0xFF);
+ if (ret) {
+ return ret;
+ }
+ ret = fs_sdio_writeb(fdev, 0, SDIO_FBR_BLK_SIZE(1)+1, (fdev->max_blocksize >> 8) & 0xFF);
+ if (ret) {
+ return ret;
+ }
+
+err:
+ return ret;
+}
+
+
+int
+fs_sdio_set_max_clock_speed(struct sdio_dev *fdev, int max_khz)
+{
+ struct mmc_card *card = fdev->card;
+
+ /* Respect the host controller's min-max. */
+ max_khz *= 1000;
+ if (max_khz < card->host->f_min) {
+ max_khz = card->host->f_min;
+ }
+ if (max_khz > card->host->f_max) {
+ max_khz = card->host->f_max;
+ }
+
+ card->host->ios.clock = max_khz;
+ card->host->ops->set_ios(card->host, &card->host->ios);
+
+ return max_khz/1000;
+}
+
+int fs_sdio_set_block_size(struct sdio_dev *fdev, int blksz)
+{
+ return 0;
+}
+
+#ifdef CONFIG_MX31_3STACK
+
+extern struct mxcmci_host *mxc_get_mmc_host(int id);
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Turn on the power of WIFI card
+ *
+ * ---------------------------------------------------------------------------
+ */
+static void fs_unifi_power_on( int check_card )
+{
+ struct mxcmci_host * mmc_host = mxc_get_mmc_host(1);
+ t_regulator_voltage voltage;
+
+ /* All comments below for SPF-23250_REV_D and SPF_23251_REV_B */
+
+ /* GPO3 -> enables SW2B 1.8V out - this becomes 1V8 on personality board,
+ * then 1V8_EXT, then BT_VUSB
+ */
+ pmic_power_regulator_on(REGU_GPO3);
+
+ /* GPO4 -> WiFi_PWEN, but this signal is not used on current boards */
+ pmic_power_regulator_on(REGU_GPO4);
+
+ /* VRF1 -> WL_1V5ANA and WL_1V5BB */
+ voltage.vrf1 = VRF1_1_5V;//VRF1_2_775V
+ pmic_power_regulator_set_voltage(REGU_VRF1, voltage);
+ pmic_power_regulator_on(REGU_VRF1);
+
+ /* VMMC2 -> WL_VDD and WL_VPA */
+ voltage.vmmc2 = VMMC2_3V;
+ pmic_power_regulator_set_voltage(REGU_VMMC2, voltage);
+ pmic_power_regulator_on(REGU_VMMC2);
+
+ /* WL_1V5DD should come on last, 10ms after other supplies */
+ mdelay(10);
+ /* VRF2 -> WL_1V5DD */
+ voltage.vrf2 = VRF2_1_5V;//VRF1_2_775V
+ pmic_power_regulator_set_voltage(REGU_VRF2, voltage);
+ pmic_power_regulator_on(REGU_VRF2);
+
+ clk_enable(mmc_host->clk);
+
+ /* MX31_PIN_DCD_DCE1 is connected to both WiFi and BT reset - this will reset BT */
+ /* So don't do it - assume the power up has reset the device */
+ /* mxc_set_gpio_dataout(MX31_PIN_DCD_DCE1, 0); */ //Low
+ /* mdelay(10); */
+ mxc_set_gpio_dataout(MX31_PIN_DCD_DCE1, 1); //high
+ mdelay(10);
+
+ if( check_card && mmc_host ) {
+ mmc_detect_change(mmc_host->mmc, msecs_to_jiffies(100));
+ }
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Turn off the power of WIFI card
+ *
+ * ---------------------------------------------------------------------------
+ */
+static void fs_unifi_power_off( int check_card )
+{
+ struct mxcmci_host * mmc_host = mxc_get_mmc_host(1);
+
+ if( check_card && mmc_host )
+ {
+ mmc_detect_change(mmc_host->mmc, msecs_to_jiffies(50));
+ mdelay(10);
+ clk_disable(mmc_host->clk);
+ }
+
+ /* Don't switch off, will switch off bluetooth! */
+ /* pmic_power_regulator_off(REGU_GPO3); */
+
+ pmic_power_regulator_off(REGU_GPO4);
+ pmic_power_regulator_off(REGU_VRF1);
+
+ pmic_power_regulator_off(REGU_VRF2);
+
+ pmic_power_regulator_off(REGU_VMMC2);
+
+ /* Don't do this, will hold Bluetooth in reset */
+ /* mxc_set_gpio_dataout(MX31_PIN_DCD_DCE1, 0); */ //Low
+}
+
+/* This should be made conditional on being slot 2 too - so we can
+ * use a plug in card in slot 1
+ */
+int fs_sdio_hard_reset(struct sdio_dev *fdev)
+{
+ fs_unifi_power_off( 0 );
+ mdelay(100);
+ fs_unifi_power_on( 0 );
+ mdelay(100);
+ /* We did a hard reset, so return 0 */
+ return 0;
+}
+
+#else /* #ifdef CONFIG_MX31_3STACK */
+
+int fs_sdio_hard_reset(struct sdio_dev *fdev)
+{
+ printk("%s: called\n", __FUNCTION__ );
+
+ /* We did not do a hard reset, so return 1 */
+ return 1;
+}
+
+static void fs_unifi_power_on( int check_card )
+{
+ (void)check_card;
+}
+
+static void fs_unifi_power_off( int check_card )
+{
+ (void)check_card;
+}
+
+#endif /* ! CONFIG_MX31_3STACK */
+
+static struct mmc_driver mmc_driver = {
+ .drv = {
+ .name = "fs_sdio",
+ },
+ .probe = fs_sdio_probe,
+ .remove = fs_sdio_remove,
+ .suspend = fs_sdio_suspend,
+ .resume = fs_sdio_resume,
+};
+
+
+
+int fs_sdio_register_driver(struct fs_driver *driver)
+{
+ int ret;
+
+ printk(KERN_INFO "fs_sdio_register_driver\n");
+
+ /* Switch us on */
+ fs_unifi_power_on(-1);
+
+ /* Store the context to the device driver to the global */
+ available_driver = driver;
+
+ /*
+ * If available_sdio_dev is not NULL, probe has been called,
+ * so pass the probe to the registered driver
+ */
+ if (available_sdio_dev) {
+ /* Store the context to the new device driver */
+ available_sdio_dev->driver = driver;
+ /* Do a bit of initialisation */
+ sdio_card_read_info(available_sdio_dev);
+
+ printk(KERN_INFO "fs_sdio_register_driver: Glue exists, add device driver and register IRQ\n");
+ driver->probe(available_sdio_dev);
+
+ /* Register the IRQ handler to the SDIO IRQ. */
+ ret = request_irq(available_sdio_dev->card->host->sdio_irq,
+ fs_sdio_irq, 0, mmc_driver.drv.name, available_sdio_dev->card);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+
+void fs_sdio_unregister_driver(struct fs_driver *driver)
+{
+ printk(KERN_INFO "fs_sdio_unregister_driver\n");
+
+ /*
+ * If available_sdio_dev is not NULL, probe has been called,
+ * so pass the remove to the registered driver to clean up.
+ */
+ if (available_sdio_dev) {
+ printk(KERN_INFO "fs_sdio_unregister_driver: Glue exists, unregister IRQ and remove device driver\n");
+
+ /* Unregister the IRQ handler first. */
+ free_irq(available_sdio_dev->card->host->sdio_irq, available_sdio_dev->card);
+
+ driver->remove(available_sdio_dev);
+
+ /* Invalidate the context to the device driver */
+ available_sdio_dev->driver = NULL;
+ }
+
+ /* Power down the UniFi */
+ fs_unifi_power_off( -1 );
+
+ /* invalidate the context to the device driver to the global */
+ available_driver = NULL;
+}
+
+
+static irqreturn_t fs_sdio_irq(int irq, void *devid)
+{
+ struct sdio_dev *fdev = (struct sdio_dev*) mmc_get_drvdata((struct mmc_card*)devid);
+
+ if (fdev->driver) {
+ if (fdev->driver->card_int_handler) {
+ fdev->driver->card_int_handler(fdev);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+#ifdef CONFIG_PM
+static int fs_sdio_suspend(struct mmc_card *card, pm_message_t state)
+{
+ struct sdio_dev *fdev = (struct sdio_dev*)mmc_get_drvdata(card);
+
+ /* Pass event to the registered driver. */
+ if (fdev->driver) {
+ if (fdev->driver->suspend) {
+ fdev->driver->suspend(fdev, state);
+ }
+ }
+
+ return 0;
+}
+
+static int fs_sdio_resume(struct mmc_card *card)
+{
+ struct sdio_dev *fdev = (struct sdio_dev*)mmc_get_drvdata(card);
+
+ /* Pass event to the registered driver. */
+ if (fdev->driver) {
+ if (fdev->driver->resume) {
+ fdev->driver->resume(fdev);
+ }
+ }
+
+ return 0;
+}
+#else
+#define fs_sdio_suspend NULL
+#define fs_sdio_resume NULL
+#endif
+
+
+
+static int fs_sdio_probe(struct mmc_card *card)
+{
+ struct sdio_dev *fdev;
+ int ret = 0;
+
+ /*
+ * Set the pull-ups, this code should really be part of the MMC driver.
+ * The IOMUXC_BASE_ADDR and the values set to the registers are platform
+ * specific, so this code may not compile or do the right thing
+ * on a different platform.
+ */
+#ifdef CONFIG_ARCH_MX3
+ writel(0x1a569485, IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x168);
+ writel(0x0a5295a5, IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x16C);
+#endif
+
+ /* Allocate our private context */
+ fdev = kmalloc(sizeof(struct sdio_dev), GFP_KERNEL);
+ memset(fdev, 0, sizeof(struct sdio_dev));
+ fdev->int_enabled = 1;
+ fdev->lock = SPIN_LOCK_UNLOCKED;
+ fdev->card = card;
+ /* Store our context to the global pointer */
+ available_sdio_dev = fdev;
+
+ /* Register the card context to the MMC driver. */
+ card->scr.bus_widths = SD_SCR_BUS_WIDTH_4;
+ card->csd.max_dtr = 1000000;
+ /*
+ * Set a default SDIO block size,
+ * override it when we read the block size from the device.
+ */
+ card->csd.read_blkbits = 64*8;
+ card->csd.write_blkbits = 64*8;
+ card->csd.read_partial = 1;
+ card->csd.write_partial = 1;
+
+ /* Store our context in the MMC driver */
+ printk(KERN_INFO "fs_sdio_probe: Add glue driver\n");
+ mmc_set_drvdata(card, fdev);
+
+ /* TODO: If a device driver is registered, call it's probe here */
+ if (available_driver) {
+ /* Store the context to the device driver */
+ fdev->driver = available_driver;
+ /* Do a bit of initialisation */
+ sdio_card_read_info(fdev);
+
+ printk(KERN_INFO "fs_sdio_probe: Add device driver and register IRQ\n");
+ available_driver->probe(fdev);
+
+ /* Register the IRQ handler to the SDIO IRQ. */
+ ret = request_irq(card->host->sdio_irq, fs_sdio_irq, 0, mmc_driver.drv.name, card);
+ if (ret) {
+ return ret;
+ }
+
+ }
+
+ return 0;
+}
+
+static void fs_sdio_remove(struct mmc_card *card)
+{
+ struct sdio_dev *fdev = (struct sdio_dev*)mmc_get_drvdata(card);
+
+ /* If there is a registered device driver, pass on the remove */
+ if (fdev->driver) {
+ printk(KERN_INFO "fs_sdio_remove: Free IRQ and remove device driver\n");
+ /* Unregister the IRQ handler first. */
+ free_irq(card->host->sdio_irq, card);
+
+ fdev->driver->remove(fdev);
+ }
+
+ printk(KERN_INFO "fs_sdio_remove: Remove glue driver\n");
+ /* Unregister the card context from the MMC driver. */
+ mmc_set_drvdata(card, NULL);
+
+ /* Invalidate the global to our context. */
+ available_sdio_dev = NULL;
+ kfree(fdev);
+
+ return;
+}
+
+
+
+/* Module init and exit, register and unregister to the SDIO/MMC driver */
+static int __init fs_sdio_init(void)
+{
+ printk(KERN_INFO "Freescale: Register to MMC/SDIO driver\n");
+ /* Sleep a bit - otherwise if the mmc subsystem has just started, it will
+ * allow us to register, then immediatly remove us!
+ */
+ msleep(10);
+ return mmc_register_driver(&mmc_driver);
+}
+module_init(fs_sdio_init);
+
+static void __exit fs_sdio_exit(void)
+{
+ printk(KERN_INFO "Freescale: Unregister from MMC/SDIO driver\n");
+ mmc_unregister_driver(&mmc_driver);
+}
+module_exit(fs_sdio_exit);
+
+
+MODULE_DESCRIPTION("Freescale SDIO glue driver");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL");
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_sdio_api.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_sdio_api.h
new file mode 100644
index 0000000..c227ae4
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_freescale/fs_sdio_api.h
@@ -0,0 +1,58 @@
+/*
+ * Freescale SDIO glue module API.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ */
+#ifndef _FS_SDIO_API_H
+#define _FS_SDIO_API_H
+
+struct sdio_dev;
+
+struct fs_driver {
+ const char *name;
+ int (*probe)(struct sdio_dev *fdev);
+ void (*remove)(struct sdio_dev *fdev);
+ void (*card_int_handler)(struct sdio_dev *fdev);
+ void (*suspend)(struct sdio_dev *fdev, pm_message_t state);
+ void (*resume)(struct sdio_dev *fdev);
+};
+
+
+int fs_sdio_readb(struct sdio_dev *fdev, int funcnum,
+ unsigned long addr, unsigned char *pdata);
+int fs_sdio_writeb(struct sdio_dev *fdev, int funcnum,
+ unsigned long addr, unsigned char data);
+int fs_sdio_block_rw(struct sdio_dev *fdev, int funcnum,
+ unsigned long addr, unsigned char *pdata,
+ unsigned int count, int direction);
+
+
+
+int fs_sdio_register_driver(struct fs_driver *driver);
+void fs_sdio_unregister_driver(struct fs_driver *driver);
+int fs_sdio_set_block_size(struct sdio_dev *fdev, int blksz);
+int fs_sdio_set_max_clock_speed(struct sdio_dev *fdev, int max_khz);
+int fs_sdio_enable_interrupt(struct sdio_dev *fdev, int enable);
+int fs_sdio_enable(struct sdio_dev *fdev);
+int fs_sdio_hard_reset(struct sdio_dev *fdev);
+
+
+struct sdio_dev {
+ struct fs_driver *driver; /**< Device driver for this module. */
+ struct mmc_card *card;
+ void *drv_data; /**< Data private to the device driver. */
+
+ int int_enabled;
+ spinlock_t lock;
+
+ uint16_t vendor_id; /**< Vendor ID of the card. */
+ uint16_t device_id; /**< Device ID of the card. */
+ int max_blocksize; /**< Maximum block size supported. */
+};
+
+
+#endif /* #ifndef _FS_SDIO_API_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc.c
new file mode 100644
index 0000000..8405987
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc.c
@@ -0,0 +1,587 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: sdio_mmc.c
+ *
+ * PURPOSE: SDIO driver interface for generic MMC stack.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/gfp.h>
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio.h>
+
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+#ifdef UNIFI_DEBUG
+
+static int Claimed;
+#define CHECK_CLAIM() do { if (!Claimed) printk("** sdio not claimed ***\n"); } while (0)
+
+#define _sdio_claim_host(_func) \
+ do { \
+ if (func->card->host->claimed) { \
+ printk("%s: host already claimed, will wait\n", __FUNCTION__); \
+ } \
+ sdio_claim_host(_func); \
+ Claimed = 1; \
+ } while (0)
+
+#define _sdio_release_host(_func) \
+ do { \
+ if (!func->card->host->claimed) { \
+ printk("%s: host not claimed\n", __FUNCTION__); \
+ } \
+ sdio_release_host(_func); \
+ Claimed = 0; \
+ } while (0)
+
+#else
+
+#define CHECK_CLAIM() {}
+#define _sdio_claim_host(_func) sdio_claim_host(_func)
+#define _sdio_release_host(_func) sdio_release_host(_func)
+
+#endif
+
+
+/* MMC uses ENOMEDIUM to indicate card gone away */
+#define convert_sdio_error(_r) (((_r) == -ENOMEDIUM) ? -ENODEV : (_r))
+
+
+void
+uf_sdio_claim(void *sdio)
+{
+ struct sdio_func *func = sdio;
+
+ _sdio_claim_host(func);
+}
+
+void
+uf_sdio_release(void *sdio)
+{
+ struct sdio_func *func = sdio;
+
+ _sdio_release_host(func);
+}
+
+
+int
+unifi_sdio_readb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata)
+{
+ struct sdio_func *func = sdio;
+ int err = 0;
+
+ CHECK_CLAIM();
+
+ if (funcnum == 0) {
+ *pdata = sdio_f0_readb(func, addr, &err);
+ } else {
+ *pdata = sdio_readb(func, addr, &err);
+ }
+ if (err) func_exit_r(err);
+
+ return convert_sdio_error(err);
+} /* unifi_sdio_readb() */
+
+int
+unifi_sdio_writeb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char data)
+{
+ struct sdio_func *func = sdio;
+ int err = 0;
+
+ CHECK_CLAIM();
+
+ if (funcnum == 0) {
+ sdio_f0_writeb(func, data, addr, &err);
+ } else {
+ sdio_writeb(func, data, addr, &err);
+ }
+ if (err) func_exit_r(err);
+
+ return convert_sdio_error(err);
+} /* unifi_sdio_writeb() */
+
+
+int
+unifi_sdio_block_rw(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata, unsigned int count, int direction)
+{
+ struct sdio_func *func = sdio;
+ int err = 0;
+
+ CHECK_CLAIM();
+
+ if (direction) {
+ err = sdio_writesb(func, addr, pdata, count);
+ } else {
+ err = sdio_readsb(func, pdata, addr, count);
+ }
+ if (err) func_exit_r(err);
+
+ return convert_sdio_error(err);
+} /* unifi_sdio_block_rw() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_set_max_clock_speed
+ *
+ * Set the maximum SDIO bus clock speed to use.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * max_khz maximum clock speed in kHz
+ *
+ * Returns:
+ * Set clock speed in kHz; or a UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_set_max_clock_speed(void *sdio, int max_khz)
+{
+ struct sdio_func *func = sdio;
+
+ CHECK_CLAIM();
+
+ if (max_khz <= 0 || max_khz > sdio_clock) {
+ max_khz = sdio_clock;
+ }
+ sdio_set_clock(func, 1000 * max_khz);
+
+ return max_khz;
+} /* unifi_sdio_set_max_clock_speed() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_enable_interrupt
+ *
+ * Enable or disable the SDIO interrupt.
+ * The driver disables the SDIO interrupt until the i/o thread can
+ * process it.
+ * The SDIO interrupt can be disabled by modifying the SDIO_INT_ENABLE
+ * register in the Card Common Control Register block, but this requires
+ * two CMD52 operations. A better solution is to mask the interrupt at
+ * the host controller.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * enable If zero disable (or mask) the interrupt, otherwise
+ * enable (or unmask) it.
+ *
+ * Returns:
+ * Zero on success or a UniFi driver error code.
+ *
+ * Notes:
+ * Called from unifi_bh() and unifi_sdio_interrupt_handler().
+ * The SDIO host is claimed by uf_sdio_claim() around unifi_bh() or
+ * by the MMC core interrupt processing.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_enable_interrupt(void *sdio, int enable)
+{
+ struct sdio_func *func = sdio;
+ int err = 0;
+
+ func_enter();
+
+ if (enable) {
+ sdio_f0_writeb(func, 0x3, SDIO_CCCR_IENx, &err);
+ } else {
+ sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &err);
+ }
+
+ func_exit();
+ return convert_sdio_error(err);
+} /* unifi_sdio_enable_interrupt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_enable
+ *
+ * Enable i/o on function 1.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_enable(void *sdio)
+{
+ struct sdio_func *func = sdio;
+ int err = 0;
+
+ func_enter();
+
+ /* Enable UniFi function 1 (the 802.11 part). */
+ err = sdio_enable_func(func);
+ if (err) {
+ unifi_error(NULL, "Failed to enable SDIO function %d\n", func->num);
+ }
+
+ func_exit();
+ return convert_sdio_error(err);
+} /* unifi_sdio_enable() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_disable
+ *
+ * Enable i/o on function 1.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_disable(void *sdio)
+{
+ struct sdio_func *func = sdio;
+ int err = 0;
+
+ func_enter();
+
+ /* Enable UniFi function 1 (the 802.11 part). */
+ err = sdio_disable_func(func);
+ if (err) {
+ unifi_error(NULL, "Failed to disable SDIO function %d\n", func->num);
+ }
+
+ func_exit();
+ return convert_sdio_error(err);
+} /* unifi_sdio_disable() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_active
+ *
+ * No-op as the bus goes to an active state at the start of every
+ * command.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_sdio_active(void *sdio)
+{
+ struct sdio_func *func = sdio;
+ /* Restart SDIO bus clock */
+ sdio_set_clock(func, 1000 * sdio_clock);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_idle
+ *
+ * Set the function as idle.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_sdio_idle(void *sdio)
+{
+ struct sdio_func *func = sdio;
+
+ sdio_set_clock(func, func->card->host->f_min);
+} /* unifi_sdio_idle() */
+
+
+/*
+ * Try using mmc_suspend_host() and mmc_resume_host() for power control
+ * and h/w reset.
+ * Note: Suspend and resume bus ops are not supported by the SDIO driver.
+ */
+int unifi_sdio_power_on(void *sdio)
+{
+#if 0
+ struct sdio_func *func = sdio;
+ sdio_resume_host(func);
+#endif
+ return 0; /* 0 means power was off, reinit required */
+}
+
+void unifi_sdio_power_off(void *sdio)
+{
+#if 0
+ struct sdio_func *func = sdio;
+ sdio_suspend_host(func, PMSG_SUSPEND);
+#endif
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_hard_reset
+ *
+ * Hard Resets UniFi is possible.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * 1 if the SDIO driver is not capable of doing a hard reset.
+ * 0 if a hard reset was successfully performed.
+ * -EIO if an I/O error occured while re-initializing the
+ * card. This is a fatal, non-recoverable error.
+ * -ENODEV if the card is no longer present.
+ * ---------------------------------------------------------------------------
+ */
+int unifi_sdio_hard_reset(void *sdio)
+{
+ return 1;
+} /* unifi_sdio_hard_reset() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_get_info
+ *
+ * Return UniFi information read by the SDIO driver.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * param_type The enum value for the required information
+ * param_value Pointer to store the returned information
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_get_info(void *sdio, enum unifi_sdio_request param_type, unsigned int *param_value)
+{
+ struct sdio_func *func = sdio;
+
+ switch (param_type) {
+ case UNIFI_SDIO_IO_BLOCK_SIZE:
+ *param_value = func->cur_blksize;
+ break;
+ case UNIFI_SDIO_VENDOR_ID:
+ *param_value = func->vendor;
+ break;
+ case UNIFI_SDIO_DEVICE_ID:
+ *param_value = func->device;
+ break;
+ case UNIFI_SDIO_FUNCTION_NUM:
+ *param_value = func->num;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+
+} /* unifi_sdio_get_info() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_int_handler
+ *
+ * Interrupt callback function for SDIO interrupts.
+ * This is called in kernel context (i.e. not interrupt context).
+ * We retrieve the unifi context pointer and call the main UniFi
+ * interrupt handler.
+ *
+ * Arguments:
+ * fdev SDIO context pointer
+ *
+ * Returns:
+ * None.
+ *
+ * Note: Called with host already claimed.
+ * ---------------------------------------------------------------------------
+ */
+static void
+uf_sdio_int_handler(struct sdio_func *func)
+{
+ unifi_priv_t *priv;
+
+ priv = sdio_get_drvdata(func);
+
+ if (priv) {
+ unifi_sdio_interrupt_handler(priv->card);
+ }
+} /* uf_sdio_int_handler() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_probe
+ *
+ * Card insert callback.
+ *
+ * Arguments:
+ * fdev SDIO context pointer
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ void *priv;
+ int instance;
+ int r;
+
+ func_enter();
+
+ _sdio_claim_host(func);
+
+ /* Assumes one card per host, which is true for SDIO */
+ instance = func->card->host->index;
+ unifi_info(NULL, "card 0x%X inserted\n", instance);
+
+ /* Always override default SDIO bus clock */
+ unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock);
+ sdio_set_clock(func, 1000 * sdio_clock);
+
+ /* Hook up our interupt handler */
+ r = sdio_claim_irq(func, uf_sdio_int_handler);
+ if (r) {
+ printk(KERN_ERR "Failed to claim SDIO interrupt: error %d\n", r);
+ }
+
+ printk("sdio bus_id: %16s\n", sdio_func_id(func));
+ /* Register this device with the main UniFi driver */
+ priv = register_unifi_sdio(func, instance, &func->dev);
+ if (!priv) {
+ sdio_release_irq(func);
+ _sdio_release_host(func);
+ func_exit();
+ return -ENOMEM;
+ }
+
+ sdio_set_drvdata(func, priv);
+
+ _sdio_release_host(func);
+
+ func_exit();
+ return 0;
+} /* uf_sdio_probe() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_remove
+ *
+ * Card removal callback.
+ *
+ * Arguments:
+ * fdev SDIO device
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+static void
+uf_sdio_remove(struct sdio_func *func)
+{
+ func_enter();
+
+ unifi_info(NULL, "card removed\n");
+
+ _sdio_claim_host(func);
+ sdio_release_irq(func);
+ _sdio_release_host(func);
+
+ /* Clean up the main UniFi driver */
+ unregister_unifi_sdio(func->card->host->index);
+
+ func_exit();
+
+} /* uf_sdio_remove */
+
+
+
+
+static const struct sdio_device_id unifi_ids[] = {
+ { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_1) },
+ { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_3) },
+ { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_4) },
+ { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(sdio, unifi_ids);
+
+static struct sdio_driver unifi_driver = {
+ .probe = uf_sdio_probe,
+ .remove = uf_sdio_remove,
+ .name = "unifi",
+ .id_table = unifi_ids,
+};
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_load
+ * uf_sdio_unload
+ *
+ * These functions are called from the main module load and unload
+ * functions. They perform the appropriate operations for the monolithic
+ * driver.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int __init
+uf_sdio_load(void)
+{
+ int r;
+
+ printk("Unifi: Using native Linux MMC driver for SDIO\n");
+
+ r = sdio_register_driver(&unifi_driver);
+ if (r) {
+ printk(KERN_ERR "unifi_sdio: Failed to register UniFi SDIO driver: %d\n", r);
+ return r;
+ }
+
+ return 0;
+} /* uf_sdio_load() */
+
+
+
+void __exit
+uf_sdio_unload(void)
+{
+ printk("unload sdio_mmc\n");
+ sdio_unregister_driver(&unifi_driver);
+} /* uf_sdio_unload() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc_fs.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc_fs.c
new file mode 100644
index 0000000..49ca0d1
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mmc_fs.c
@@ -0,0 +1,221 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: sdio_mmc_fs.c
+ *
+ * This file provides the portable driver bottom-edge API implementation
+ * for the Freescale imx31ads platform, using the Freescale SDIO glue module.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "unifi_priv.h"
+
+#include "sdio_freescale/fs_sdio_api.h"
+
+
+static int fs_probe(struct sdio_dev *fdev);
+static void fs_remove(struct sdio_dev *fdev);
+
+
+int
+unifi_sdio_readb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata)
+{
+
+ return fs_sdio_readb(sdio, funcnum, addr, pdata);
+}
+
+
+int
+unifi_sdio_writeb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char data)
+{
+ return fs_sdio_writeb(sdio, funcnum, addr, data);
+}
+
+
+int
+unifi_sdio_block_rw(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata, unsigned int count, int direction)
+{
+ return fs_sdio_block_rw(sdio, funcnum, addr,pdata, count, direction);
+}
+
+
+
+int
+unifi_sdio_enable_interrupt(void *sdio, int enable)
+{
+ return fs_sdio_enable_interrupt(sdio, enable);
+}
+
+
+
+int
+unifi_sdio_get_info(void *sdio, enum unifi_sdio_request param_type, unsigned int *param_value)
+{
+ struct sdio_dev *fdev = (struct sdio_dev*) sdio;
+
+ switch (param_type) {
+ case UNIFI_SDIO_IO_BLOCK_SIZE:
+
+ *param_value = fdev->max_blocksize;
+ break;
+
+ case UNIFI_SDIO_VENDOR_ID:
+
+ *param_value = fdev->vendor_id;
+ break;
+
+ case UNIFI_SDIO_DEVICE_ID:
+
+ *param_value = fdev->device_id;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+
+} /* unifi_sdio_get_info() */
+
+void
+unifi_sdio_active(void *sdio)
+{
+}
+
+void
+unifi_sdio_idle(void *sdio)
+{
+}
+
+
+int
+unifi_sdio_enable(void *sdio)
+{
+ return fs_sdio_enable(sdio);
+}
+
+
+int
+unifi_sdio_set_max_clock_speed(void *sdio, int max_khz)
+{
+ /* Respect the max set by the module parameter. */
+ if (max_khz <= 0 || max_khz > sdio_clock) {
+ max_khz = sdio_clock;
+ }
+
+ return fs_sdio_set_max_clock_speed(sdio, max_khz);
+
+} /* unifi_sdio_set_max_clock_speed() */
+
+
+int
+unifi_sdio_hard_reset(void *sdio)
+{
+ return fs_sdio_hard_reset(sdio);
+} /* unifi_sdio_hard_reset() */
+
+
+
+static void
+fs_int_handler(struct sdio_dev *fdev)
+{
+ unifi_priv_t *priv = fdev->drv_data;
+
+ unifi_sdio_interrupt_handler(priv->card);
+}
+
+
+
+#ifdef CONFIG_PM
+static void fs_suspend(struct sdio_dev *fdev, pm_message_t state)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)fdev->drv_data;
+
+ unifi_trace(priv, UDBG3, "Suspending...\n");
+ /* Pass event to UniFi Driver. */
+ unifi_suspend(priv);
+
+}
+
+static void fs_resume(struct sdio_dev *fdev)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)fdev->drv_data;
+
+ unifi_trace(priv, UDBG3, "Resuming...\n");
+ /* Pass event to UniFi Driver. */
+ unifi_resume(priv);
+
+}
+#else
+#define mmc_uf_suspend NULL
+#define mmc_uf_resume NULL
+#endif
+
+
+static struct fs_driver fs_driver = {
+ .name = "fs_driver",
+ .probe = fs_probe,
+ .remove = fs_remove,
+ .card_int_handler = fs_int_handler,
+ .suspend = fs_suspend,
+ .resume = fs_resume,
+};
+
+
+int __init
+uf_sdio_load(void)
+{
+ printk("Unifi: Using MMC/SDIO glue driver\n");
+ return fs_sdio_register_driver(&fs_driver);
+}
+
+
+void __exit
+uf_sdio_unload(void)
+{
+ fs_sdio_unregister_driver(&fs_driver);
+}
+
+
+static int fs_probe(struct sdio_dev *fdev)
+{
+ void *dev_priv;
+
+ unifi_info(NULL, "card inserted\n");
+
+ /* Always override default SDIO bus clock */
+ unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock);
+ fs_sdio_set_max_clock_speed(fdev, sdio_clock);
+
+
+ /* Register this device with the main UniFi driver */
+ dev_priv = (void*)register_unifi_sdio(fdev, 0, NULL);
+
+ fdev->drv_data = dev_priv;
+
+ return 0;
+}
+
+static void fs_remove(struct sdio_dev *fdev)
+{
+ unifi_info(NULL, "card removed\n");
+
+ /* Clean up the main UniFi driver */
+ unregister_unifi_sdio(0);
+
+ return;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mobstor.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mobstor.c
new file mode 100644
index 0000000..3b4529a
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_mobstor.c
@@ -0,0 +1,1043 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: sdio_3dlabs.c
+ *
+ * PURPOSE: Driver instantiation and deletion for SDIO on 3dlabs DMS-05.
+ *
+ * This file brings together the SDIO bus interface and the UniFi
+ * driver core.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ *
+ * NOTES:
+ *
+ * This file was written to support the 3D Labs DMS-05 EVM board.
+ *
+ * The SDIO/SD/MMC slots are:
+ * 0 4G Flash memory
+ * 1 SDIO connector
+ * 2 Marvell WiFi
+ *
+ * The Marvell WiFi registers itself as network device "wifi0" and
+ * works with iwconfig and iwlist.
+ *
+ *
+ * CHANGES TO PLATFORM:
+ * Modified modprobe.conf to disable sd8xxx (Marvell driver) and change
+ * wifi to alias unifi_sdio.
+ *
+ * To start UniFi:
+ * mmcconfig remove 2
+ * modprobe unifi_sdio
+ * mmcconfig remove 1
+ * mmcconfig add 1
+ * (could modify /etc/init.d/rcS to do this)
+ *
+ * Note: the unifi_helper and unififw script must be installed in /usr/sbin.
+ * ---------------------------------------------------------------------------
+ */
+/* The code here was based on Jens sdio_mobs.c file */
+
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include "mobstor_sdio_bus.h"
+
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+#define USE_POLLING
+
+
+static int Interrupt_enabled = 0;
+#define BOUNCE_BUFF_SIZE 1600
+static u8 *Bounce_buff = NULL;
+
+
+static int
+convert_sdio_error(unsigned int r)
+{
+ int err = 0;
+
+ if (r == 0) return 0;
+
+ switch (r) {
+
+ case ERRCMDINPROGRESS:
+ case ERRCRC:
+ case ERRECCFAILED:
+ case ERRCCERR:
+ case ERRUNDERRUN:
+ case ERROVERRUN:
+ case ERRUNDERWRITE:
+ case ERROVERREAD:
+ case ERRENDBITERR:
+ case ERRDCRC:
+ case ERRSTARTBIT:
+ err = -EIO;
+ break;
+
+ case ERRRESPTIMEOUT:
+ case ERRCMDRETRIESOVER:
+ case ERRDATATIMEOUT:
+ case ERRTIMEROUT:
+ err = -ETIMEDOUT;
+ break;
+
+ case ERRCARDNOTFOUND:
+ case ERRCARDNOTCONN:
+ err = -ENODEV;
+ break;
+
+ default:
+ case ERRCMDNOTSUPP:
+ case ERRINVALIDCARDNUM:
+ case ERRNOTSUPPORTED:
+ case ERRRESPRECEP:
+ case ERRENUMERATE:
+ case ERRHARDWARE:
+ case ERRNOMEMORY:
+ case ERRFSMSTATE:
+ case ERRADDRESSRANGE:
+ case ERRADDRESSMISALIGN:
+ case ERRBLOCKLEN:
+ case ERRERASESEQERR:
+ case ERRERASEPARAM:
+ case ERRPROT:
+ case ERRCARDLOCKED:
+ case ERRILLEGALCOMMAND:
+ case ERRUNKNOWN:
+ case ERRCSDOVERWRITE:
+ case ERRERASERESET:
+ case ERRCARDNOTREADY:
+ case ERRBADFUNC:
+ case ERRPARAM:
+ case ERRNOTFOUND:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+} /* convert_sdio_error() */
+
+
+#define CISTPL_NULL 0x00
+#define CISTPL_CHECKSUM 0x10
+#define CISTPL_VERS_1 0x15
+#define CISTPL_ALTSTR 0x16
+#define CISTPL_MANFID 0x20
+# define CISTPL_MANFID_SIZE 0x04
+#define CISTPL_FUNCID 0x21
+#define CISTPL_FUNCE 0x22
+#define CISTPL_SDIO_STD 0x91
+#define CISTPL_SDIO_EXT 0x92
+#define CISTPL_END 0xff
+#define CISTPL_FUNCE 0x22
+# define CISTPL_FUNCE_00_SIZE 0x04
+# define CISTPL_FUNCE_01_SIZE 0x2a
+
+
+static u32
+get_tuple(MobsHostInfo_t * mobs_unit, u32 slot, u32 func, u8 ident, u32 len,
+ u8 * output_buffer)
+{
+ u32 retval;
+ u8 current_tuple = 0;
+ u8 length;
+ u8 buf[3];
+ u32 cis;
+ u32 saved_cis = 0;
+
+
+ if ((0 == ident) || (0xff == ident)) {
+ printk("Bad Ident : 0x%02x\n", ident);
+ return ERRPARAM;
+ }
+
+
+ if((retval = bus_io_rw_52(mobs_unit, slot, 0, (func << 8) | 0x09, &buf[0], 0, 0)))
+ {
+ printk("Unable to read CIS pointer : %d\n", retval);
+ }
+ if((retval = bus_io_rw_52(mobs_unit, slot, 0, (func << 8) | 0x0a, &buf[1], 0, 0)))
+ {
+ printk("Unable to read CIS pointer : %d\n", retval);
+ }
+ if((retval = bus_io_rw_52(mobs_unit, slot, 0, (func << 8) | 0x0b, &buf[2], 0, 0)))
+ {
+ printk("Unable to read CIS pointer : %d\n", retval);
+ }
+
+
+ /* Now we have the cis pointer */
+ saved_cis = cis = (buf[2] << 16) | (buf[1] << 8) | buf[0];;
+
+
+ if ((cis < 0x0001000) || (cis > 0x017fff)) {
+ printk("CIS pointer out of range : 0x%08x\n", cis);
+ return ERRHARDWARE;
+ }
+
+ while ((current_tuple != 0xff) && (current_tuple != ident)) {
+ if ((retval =
+ bus_io_rw_52(mobs_unit, slot, 0, cis, &current_tuple, 0,
+ 0))) {
+ printk("Unable to read tuple ident @ 0x%08x\n", cis);
+ return retval;
+ }
+
+
+ if ((retval =
+ bus_io_rw_52(mobs_unit, slot, 0, cis + 1, &length, 0, 0))) {
+ printk("Unable to read tuple length @ 0x%08x\n", cis + 1);
+ return retval;
+ }
+ saved_cis = cis;
+ cis += (length + 2);
+ }
+
+ if (current_tuple == ident) {
+ int i;
+
+ if (length < len) {
+ /* buffer is smaller than tuple */
+ len = length;
+ }
+
+ for (i = 0; i < len; i++) {
+ retval =
+ bus_io_rw_52(mobs_unit, slot, 0, saved_cis + 2 + i,
+ &output_buffer[i], 0, 0);
+ if (retval) {
+ break;
+ }
+ }
+#if 0
+ if (!retval) {
+ int c;
+ printk("\n");
+ for (c = 0; c < len; c++) {
+ printk("%d ", output_buffer[c]);
+ }
+ printk("\n");
+ }
+#endif
+
+ } else {
+ retval = ERRNOTFOUND;
+ }
+
+ return retval;
+}
+
+
+static int
+get_device_ids(struct sdio_device *the_device, u16 *vendor_id, u16 *device_id)
+{
+ u8 idbuf[CISTPL_MANFID_SIZE];
+
+ /* read manfid from CIS */
+ memset(idbuf, 0, CISTPL_MANFID_SIZE);
+
+ BUG_ON(the_device == NULL);
+ BUG_ON(the_device->host == NULL);
+
+ plat_get_device(the_device->host);
+ if (get_tuple(the_device->host,
+ the_device->slot_num,
+ 0 /* the_device->function_number */,
+ CISTPL_MANFID, CISTPL_MANFID_SIZE,
+ idbuf))
+ {
+ printk("Could not get tuple !\n");
+ plat_relinquish_device(the_device->host);
+ return -EIO;
+ }
+ plat_relinquish_device(the_device->host);
+
+ *vendor_id = idbuf[0] | (idbuf[1] << 8);
+ *device_id = idbuf[2] | (idbuf[3] << 8);
+
+ return 0;
+}
+
+
+static int
+print_reg(struct sdio_device *sdio_dev, int addr, const char *reg_name)
+{
+ int r = 0;
+ u8 val;
+
+ r = sdio_dev->do_single_register_io(sdio_dev, addr, &val,
+ DOREAD, FUNC0);
+ if (r) {
+ printk("Error %d reading %s\n", r, reg_name);
+ } else {
+ printk("%s=0x%X\n", reg_name, val);
+ }
+ return r;
+} /* print_reg() */
+
+
+static int
+set_block_size(struct sdio_device *sdio_dev, int blocksize)
+{
+ int r;
+ u8 val;
+#define SDIO_FUNC1_BLOCKSIZE 0x110
+
+ val = blocksize & 0xFF;
+ printk("writing 0x%x to 0x%X\n", val, SDIO_FUNC1_BLOCKSIZE);
+ r = sdio_dev->do_single_register_io(sdio_dev, SDIO_FUNC1_BLOCKSIZE, &val,
+ DOWRITE, FUNC0);
+ if (r) {
+ printk("Error %d writing 0x%02X to SDIO reg 0x%X\n",
+ r, val, SDIO_FUNC1_BLOCKSIZE);
+// return r;
+ }
+
+ val = (blocksize >> 8) & 0xFF;
+ printk("writing 0x%x to 0x%X\n", val, SDIO_FUNC1_BLOCKSIZE+1);
+ r = sdio_dev->do_single_register_io(sdio_dev, SDIO_FUNC1_BLOCKSIZE+1, &val,
+ DOWRITE, FUNC0);
+ if (r) {
+ printk("Error %d writing 0x%02X to SDIO reg 0x%X\n",
+ r, val, SDIO_FUNC1_BLOCKSIZE+1);
+// return r;
+ }
+
+ print_reg(sdio_dev, 0x110, "F1_BLOCKSIZE_LO");
+ print_reg(sdio_dev, 0x111, "F1_BLOCKSIZE_HI");
+
+ return r;
+} /* set_block_size() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_readb
+ * unifi_sdio_writeb
+ * unifi_sdio_block_rw
+ *
+ * Basic SDIO read/write functions
+ *
+ * Arguments:
+ *
+ *
+ * Returns:
+ * 0
+ * -EINVAL
+ * -EIO
+ * -ETIMEDOUT
+ * -ENODEV
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_readb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata)
+{
+ struct sdio_device *sdio_dev = sdio;
+ unsigned int err;
+
+ err = sdio_dev->do_single_register_io(sdio_dev, addr, pdata,
+ DOREAD,
+ (funcnum == 0) ? FUNC0 : OWNFUNC);
+ return convert_sdio_error(err);
+} /* unifi_sdio_readb() */
+
+int
+unifi_sdio_writeb(void *sdio, int funcnum, unsigned long addr,
+ unsigned char data)
+{
+ struct sdio_device *sdio_dev = sdio;
+ unsigned int err;
+
+ err = sdio_dev->do_single_register_io(sdio_dev, addr, &data,
+ DOWRITE,
+ (funcnum == 0) ? FUNC0 : OWNFUNC);
+ return convert_sdio_error(err);
+} /* unifi_sdio_writeb() */
+
+
+int
+unifi_sdio_block_rw(void *sdio, int funcnum, unsigned long addr,
+ unsigned char *pdata, unsigned int count, int direction)
+{
+ struct sdio_device *sdio_dev = sdio;
+ unsigned int err;
+ int nblocks;
+
+ {
+ int ofs;
+ ofs = (pdata - (unsigned char *)NULL) & 15;
+ if (ofs) {
+ //printk("%s: unaligned buffer: pdata=%p\n", __FUNCTION__, pdata);
+
+ if (count > BOUNCE_BUFF_SIZE) {
+ printk("%s: count (%d) too big for bounce buffer (%d)\n",
+ __FUNCTION__, count, BOUNCE_BUFF_SIZE);
+ return -EINVAL;
+ }
+ memcpy(Bounce_buff, pdata, count);
+ pdata = Bounce_buff;
+ }
+ }
+
+ if ((count % sdio_dev->max_block_size) != 0) {
+ printk("Invalid CMD53 byte count, whole blocks only, count=%d, blksiz=%d\n",
+ count, sdio_dev->max_block_size);
+ return -EINVAL;
+ }
+ nblocks = count / sdio_dev->max_block_size;
+
+#if 0
+ unifi_trace(NULL, UDBG1,
+ "block_rw: %c pdata=%p addr=0x%X, count=0x%X, blksiz=0x%X, nblks=0x%X\n",
+ direction ? 'W' : 'R',
+ pdata,
+ addr,
+ count,
+ sdio_dev->max_block_size,
+ nblocks);
+#endif
+
+ err = sdio_dev->do_multiple_register_io_block(
+ sdio_dev,
+ addr,
+ pdata,
+ nblocks,
+ sdio_dev->max_block_size,
+ direction,
+ OWNFUNC,
+ 1 /* FIFO mode, don't inc addr */);
+
+ return convert_sdio_error(err);
+} /* unifi_sdio_block_rw() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_set_max_clock_speed
+ *
+ * Set the maximum SDIO bus clock speed to use.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * max_khz maximum clock speed in kHz
+ *
+ * Returns:
+ * Set clock speed in kHz; or a UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_set_max_clock_speed(void *sdio, int max_khz)
+{
+#define MOBS_CLK 45000
+ struct sdio_device *sdio_dev = sdio;
+ u32 card_divider;
+ int actual_khz;
+
+// printk("%s: maxkhz=%d\n", __FUNCTION__, max_khz);
+
+ /* Apply module parameter override */
+ if (max_khz <= 0 || max_khz > sdio_clock) {
+ max_khz = sdio_clock;
+ }
+
+ card_divider = MOBS_CLK / max_khz;
+
+ /*
+ * Would be good to call bus_set_clk_freq(() here,
+ * but it is not an exported symbol.
+ */
+ sdio_dev->host->cards[0].divider_val = card_divider;
+
+ actual_khz = MOBS_CLK / (card_divider+1);
+// printk("actual freq %d\n", actual_khz);
+
+ return actual_khz;
+} /* unifi_sdio_set_max_clock_speed() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_enable_interrupt
+ *
+ * Enable or disable the SDIO interrupt.
+ * The driver can be made more efficient by disabling the SDIO interrupt
+ * during processing.
+ * The SDIO interrupt can be disabled by modifying the SDIO_INT_ENABLE
+ * register in the Card Common Control Register block, but this requires
+ * two CMD52 operations. A better solution is to mask the interrupt at
+ * the host controller.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * enable If zero disable (or mask) the interrupt, otherwise
+ * enable (or unmask) it.
+ *
+ * Returns:
+ * Zero on success or a UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_enable_interrupt(void *sdio, int enable)
+{
+#ifdef USE_POLLING
+// printk("unifi_sdio_enable_interrupt: enable=%d\n", enable);
+
+#else
+ struct sdio_device *sdio_dev = sdio;
+
+// printk("unifi_sdio_enable_interrupt: enable=%d\n", enable);
+
+ if (enable == Interrupt_enabled) {
+ return 0;
+ }
+
+ if (enable) {
+#if 0
+ print_reg(sdio_dev, SDIO_REG_IOENABLE, "IO_EN");
+ print_reg(sdio_dev, SDIO_REG_INTRENABLE, "INT_EN");
+ print_reg(sdio_dev, SDIO_REG_INTRPENDING, "INT_PEND");
+#endif
+ sdio_dev->enable_device_interrupt(sdio_dev);
+ } else {
+ sdio_dev->disable_device_interrupt(sdio_dev);
+ }
+#endif /* USE_POLLING */
+
+ Interrupt_enabled = enable;
+
+ return 0;
+} /* unifi_sdio_enable_interrupt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_enable
+ *
+ * Enable i/o on function 1.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_enable(void *sdio)
+{
+ struct sdio_device *sdio_dev = sdio;
+ int count;
+ u8 ioready;
+ int r;
+
+ /* Enable UniFi function 1 (the 802.11 part). */
+ r = unifi_sdio_writeb(sdio, 0, SDIO_REG_IOENABLE, 2);
+ if (r) {
+ printk(KERN_ERR "Failed to enable func 1, sdio err=%d\n", r);
+ return convert_sdio_error(r);
+ }
+
+ /* Wait for IOREADY */
+ ioready = 0;
+ for (count = 0; count < 10; count++) {
+ r = unifi_sdio_readb(sdio_dev, 0, SDIO_REG_IOREADY, &ioready);
+ if (r) {
+ printk(KERN_ERR "Failed to read IOREADY, sdio err=%d\n", r);
+ return convert_sdio_error(r);
+ }
+ if (ioready & 0x2) {
+ break;
+ }
+ msleep(1);
+ }
+ if ((ioready & 0x2) == 0) {
+ printk(KERN_ERR "IOREADY still 0 after 100 tries\n");
+ return -ETIMEDOUT;
+ }
+
+ return r;
+} /* unifi_sdio_enable() */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_active
+ *
+ * No-op as the bus goes to an active state at the start of every
+ * command.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_sdio_active(void *sdio)
+{
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_idle
+ *
+ * Set the function as idle.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_sdio_idle(void *sdio)
+{
+} /* unifi_sdio_idle() */
+
+
+int unifi_sdio_power_on(void *sdio)
+{
+ return 1;
+}
+
+void unifi_sdio_power_off(void *sdio)
+{
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_hard_reset
+ *
+ * Hard Resets UniFi is possible.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ *
+ * Returns:
+ * 1 if the SDIO driver is not capable of doing a hard reset.
+ * 0 if a hard reset was successfully performed.
+ * -EIO if an I/O error occured while re-initializing the
+ * card. This is a fatal, non-recoverable error.
+ * -ENODEV if the card is no longer present.
+ * ---------------------------------------------------------------------------
+ */
+int unifi_sdio_hard_reset(void *sdio)
+{
+ /* Can't do it */
+ return 1;
+} /* unifi_sdio_hard_reset() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_sdio_get_info
+ *
+ * Return UniFi information read by the SDIO driver.
+ *
+ * Arguments:
+ * sdio SDIO context pointer
+ * param_type The enum value for the required information
+ * param_value Pointer to store the returned information
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_sdio_get_info(void *sdio, enum unifi_sdio_request param_type, unsigned int *param_value)
+{
+ struct sdio_device *sdio_dev = sdio;
+
+ switch (param_type) {
+ case UNIFI_SDIO_IO_BLOCK_SIZE:
+ *param_value = sdio_dev->max_block_size;
+ break;
+ case UNIFI_SDIO_VENDOR_ID:
+// *param_value = fdev->vendor_id;
+ *param_value = 0x032A; /* CSR */
+ break;
+ case UNIFI_SDIO_DEVICE_ID:
+// *param_value = fdev->device_id;
+ *param_value = 0x0001; /* UniFi-1 */
+ break;
+ case UNIFI_SDIO_FUNCTION_NUM:
+ *param_value = sdio_dev->function_number;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+
+} /* unifi_sdio_get_info() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_int_handler
+ *
+ * Interrupt callback function for SDIO interrupts.
+ * This is called in kernel context (i.e. not interrupt context).
+ * We retrieve the unifi context pointer and call the main UniFi
+ * interrupt handler.
+ *
+ * Arguments:
+ * fdev SDIO context pointer
+ *
+ * Returns:
+ * Linux error code, i.e. 0 on success -E??? on error
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_int_handler(struct sdio_device *sdio_dev)
+{
+ unifi_priv_t *priv = sdio_dev->priv_data;
+
+ /* mobstor calls this with interrupts disabled */
+// Interrupt_enabled = 0;
+
+// printk("INTERRUPT!\n");
+ unifi_sdio_interrupt_handler(priv->card);
+
+ return 0;
+} /* uf_sdio_int_handler() */
+
+
+
+
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * Polling support
+ *
+ */
+#ifdef USE_POLLING
+static long poll_thread_pid;
+static int poll_running;
+
+static int
+poll_thread_function(void *arg)
+{
+ struct sdio_device *sdio_dev = arg;
+#define POLL_INTERVAL_MS 50
+
+ daemonize("3dlabs_sdio_poll");
+ /*
+ * daemonize() disables all signals. Allow SIGTERM to wake an
+ * interruptible_sleep_on() call.
+ */
+ allow_signal(SIGTERM);
+
+ while (1) {
+ int r;
+ u8 intpend;
+
+ msleep_interruptible(POLL_INTERVAL_MS);
+ if (!poll_running) {
+ break;
+ }
+
+ if (Interrupt_enabled) {
+ r = unifi_sdio_readb(sdio_dev, 0, SDIO_REG_INTRPENDING, &intpend);
+ if (r) {
+ printk("Error reading INTPEND register: %d\n", r);
+ break;
+ }
+ //printk("INTPEND=0x%X\n", intpend);
+ //print_reg(sdio_dev, SDIO_REG_INTRENABLE, "INT_EN");
+ if (intpend & 2) {
+ uf_sdio_int_handler(sdio_dev);
+ }
+ }
+ }
+
+ printk("Polling thread exit\n");
+
+ return 0;
+} /* poll_thread_function() */
+
+
+static void
+init_polling(struct sdio_device *sdio_dev)
+{
+ poll_running = 1;
+ poll_thread_pid = kernel_thread(poll_thread_function, sdio_dev, 0);
+}
+#endif /* USE_POLLING */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_probe
+ *
+ * Card insert callback.
+ *
+ * Arguments:
+ * dev Linux device struct
+ *
+ * Returns:
+ * UniFi driver error code.
+ *
+ * Notes:
+ * The mobstor SDIO driver has not set up the sdio_device struct when
+ * this is called. The only valid fields are:
+ * dev->bus_id
+ *
+ * That means UniFi is not ready and we can't do any SDIO at this time.
+ *
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_probe(struct device *dev)
+{
+ struct sdio_device *sdio_dev = to_sdio_device(dev);
+
+ unifi_info(NULL, "uf_sdio_probe: card inserted\n");
+
+#if 0
+ printk("dev=%p, dev->bus_id \"%s\"\n", dev, dev->bus_id);
+ printk("sdio_dev=0x%p: slot %d, name 0x%p \"%s\"\n",
+ sdio_dev,
+ sdio_dev->slot_num,
+ sdio_dev->pretty_name, sdio_dev->pretty_name);
+ printk(" d_f %d, f_n %d, max_block_size %d\n",
+ sdio_dev->device_function,
+ sdio_dev->function_number,
+ sdio_dev->max_block_size);
+ printk(" host %p\n",
+ sdio_dev->host);
+
+ printk("divider_val = %d\n", sdio_dev->host->cards[0].divider_val);
+
+ sdio_dev->host->cards[0].divider_val = 10;
+ printk("divider_val now %d\n", sdio_dev->host->cards[0].divider_val);
+
+ print_reg(sdio_dev, SDIO_REG_IOABORT, "IO_ABORT");
+ print_reg(sdio_dev, SDIO_REG_IOENABLE, "IO_EN");
+ print_reg(sdio_dev, SDIO_REG_INTRENABLE, "INT_EN");
+ print_reg(sdio_dev, 0x110, "F1_BLOCKSIZE_LO");
+ print_reg(sdio_dev, 0x111, "F1_BLOCKSIZE_HI");
+#endif
+
+
+ Bounce_buff = (u8 *)kmalloc(BOUNCE_BUFF_SIZE, GFP_KERNEL);
+ if (!Bounce_buff) {
+ printk("Failed to allocate memory for bounce buffer\n");
+ return -ENOMEM;
+ }
+
+
+ {
+ int r;
+ u16 vendor_id, device_id;
+
+ r = get_device_ids(sdio_dev, &vendor_id, &device_id);
+ if (r) {
+ printk("Failed to get device ID from CIS: err %d\n", r);
+ }
+ else
+ {
+ unifi_info(NULL, "VID=%04X, PID=%04X\n", vendor_id, device_id);
+
+ if ((vendor_id != 0x032A) || /* CSR */
+ (device_id != 0x0001)) /* UniFi-1 */
+ {
+ /* Not a UniFi-1 */
+ printk("Not a UniFi-1\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ /*
+ * The mobstor seems to fail reading the CIS from UniFi, which means
+ * we don't get a proper value of max_block_size.
+ * So set it manually here.
+ */
+ sdio_dev->max_block_size = 64;
+
+ set_block_size(sdio_dev, sdio_dev->max_block_size);
+
+
+ /* Register this device with the main UniFi driver */
+ /* Only support one device, so hard-code the unifi index to 0 */
+ sdio_dev->priv_data = register_unifi_sdio(sdio_dev, 0);
+// printk("uf_sdio_probe: register_unifi_sdio returned %p\n", sdio_dev->priv_data);
+
+#ifdef USE_POLLING
+ printk("uf_sdio_probe: Polling mode\n");
+ sdio_dev->disable_device_interrupt(sdio_dev);
+ init_polling(sdio_dev);
+#endif /* USE_POLLING */
+
+ return sdio_dev->priv_data ? 0 : -ENOMEM;
+
+} /* uf_sdio_probe() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_remove
+ *
+ * Card removal callback.
+ *
+ * Arguments:
+ * dev Linux device struct
+ *
+ * Returns:
+ * UniFi driver error code.
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_remove(struct device *dev)
+{
+ struct sdio_device *sdio_dev = to_sdio_device(dev);
+
+ unifi_info(NULL, "card removed\n");
+
+#ifdef USE_POLLING
+ poll_running = 0;
+#endif /* USE_POLLING */
+
+ if (sdio_dev->disable_device_interrupt) {
+ sdio_dev->disable_device_interrupt(sdio_dev);
+ }
+
+ /* Clean up the main UniFi driver */
+ unregister_unifi_sdio(0);
+
+ if (Bounce_buff) {
+ kfree(Bounce_buff);
+ }
+ Bounce_buff = NULL;
+
+ return 0;
+} /* uf_sdio_remove */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_suspend
+ *
+ * System suspend callback.
+ *
+ * Arguments:
+ * dev Linux device struct
+ *
+ * Returns:
+ *
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_suspend(struct device *dev, pm_message_t state)
+{
+ struct sdio_device *sdio_dev = to_sdio_device(dev);
+ unifi_priv_t *priv = sdio_dev->priv_data;
+
+ unifi_trace(NULL, UDBG3, "Suspending...\n");
+ /* Pass event to UniFi Driver. */
+ unifi_suspend(priv);
+
+ return 0;
+} /* uf_sdio_suspend() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_resume
+ *
+ * System resume callback.
+ *
+ * Arguments:
+ * dev Linux device struct
+ *
+ * Returns:
+ *
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_resume(struct device *dev)
+{
+ struct sdio_device *sdio_dev = to_sdio_device(dev);
+ unifi_priv_t *priv = sdio_dev->priv_data;
+
+ unifi_trace(NULL, UDBG3, "Resuming...\n");
+ /* Pass event to UniFi Driver. */
+ unifi_resume(priv);
+
+ return 0;
+} /* uf_sdio_resume() */
+
+
+
+ /* *MUST* claim to support SDIO type WLAN or mobstor won't match us */
+static struct sdio_device_driver unifi_driver = {
+ .pretty_name = "unifi_sdio_drv",
+ .the_devids = { 1, { 7, } }, /* WLAN */
+ .priv_data = NULL,
+ .intr_handler = uf_sdio_int_handler,
+
+ .drv = {
+ .name = "unifi_sdio",
+ .owner = THIS_MODULE,
+ .probe = uf_sdio_probe,
+ .remove = uf_sdio_remove,
+ .suspend = uf_sdio_suspend,
+ .resume = uf_sdio_resume,
+ },
+};
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_load
+ * uf_sdio_unload
+ *
+ * These functions are called from the main module load and unload
+ * functions. They perform the appropriate operations for the monolithic
+ * driver.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int __init
+uf_sdio_load(void)
+{
+ int r;
+
+ printk("Unifi: Using Mobstor SDIO driver\n");
+
+ r = sdio_driver_register(&unifi_driver);
+ if (r) {
+ unifi_error(NULL, "Failed to register UniFi driver with SDIO: %d\n", r);
+ return r;
+ }
+
+ printk("uf_sdio_load: done\n");
+ return 0;
+} /* uf_sdio_load() */
+
+
+
+void __exit
+uf_sdio_unload(void)
+{
+ sdio_driver_unregister(&unifi_driver);
+} /* uf_sdio_unload() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_stubs.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_stubs.c
new file mode 100644
index 0000000..46ff774
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sdio_stubs.c
@@ -0,0 +1,54 @@
+/*
+ * Stubs for some of the bottom edge functions.
+ *
+ * These stubs are optional functions in the bottom edge (SDIO driver
+ * interface) API that not all platforms or SDIO drivers may support.
+ *
+ * They're declared as weak symbols so they can be overridden by
+ * simply providing a non-weak declaration.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ */
+#include "driver/unifi.h"
+
+void __attribute__((weak)) unifi_sdio_idle(void *sdio)
+{
+}
+
+void __attribute__((weak)) unifi_sdio_active(void *sdio)
+{
+}
+
+int __attribute__((weak)) unifi_sdio_power_on(void *sdio)
+{
+ return 0;
+}
+
+void __attribute__((weak)) unifi_sdio_power_off(void *sdio)
+{
+}
+
+int __attribute__((weak)) unifi_sdio_hard_reset(void *sdio)
+{
+ return 1;
+}
+
+void __attribute__((weak)) unifi_sdio_suspend(void *sdio)
+{
+}
+
+void __attribute__((weak)) unifi_sdio_resume(void *sdio)
+{
+}
+
+void __attribute__((weak)) uf_sdio_claim(void *sdio)
+{
+}
+
+void __attribute__((weak)) uf_sdio_release(void *sdio)
+{
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.c
new file mode 100644
index 0000000..8224cdc
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.c
@@ -0,0 +1,799 @@
+/* This is an autogenerated file from sme__build_signal_c.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#include "fsm/fsm.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "smeio/smeio_fsm_events.h"
+#include "event_pack_unpack/event_pack_unpack.h"
+
+uint16 build_packed_unifi_mgt_wifi_on_req(uint8** resultBuffer, const unifi_MACAddress* address, const unifi_DataBlockList* mibFiles)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 6; address->data */
+ /* packedSize += 2; mibFiles->numElements */
+ {
+ int i;
+ for (i = 0; i < mibFiles->numElements; i++)
+ {
+ packedSize += mibFiles->datalist[i].length + 2; /*lint !e725*/ /* unifi_DataBlock :: datalist */
+ packedSize += 0;
+ }
+ }
+ packedSize += 8; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_WIFI_ON_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_buffer(&buffer, (uint8*)&address->data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_uint16(&buffer, (uint16)mibFiles->numElements); /* numElements */
+ {
+ int i;
+ for (i = 0; i < mibFiles->numElements; i++)
+ {
+ packedLength += event_pack_uint16(&buffer, mibFiles->datalist[i].length); /*lint !e725 unifi_DataBlock : datalist */
+ packedLength += event_pack_buffer(&buffer, mibFiles->datalist[i].data, mibFiles->datalist[i].length); /*lint !e545 !e725 unifi_DataBlock : datalist */
+ }
+ }
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_wifi_off_req(uint8** resultBuffer)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_WIFI_OFF_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_wifi_flightmode_req(uint8** resultBuffer, const unifi_MACAddress* address, const unifi_DataBlockList* mibFiles)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 6; address->data */
+ /* packedSize += 2; mibFiles->numElements */
+ {
+ int i;
+ for (i = 0; i < mibFiles->numElements; i++)
+ {
+ packedSize += mibFiles->datalist[i].length + 2; /*lint !e725*/ /* unifi_DataBlock :: datalist */
+ packedSize += 0;
+ }
+ }
+ packedSize += 8; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_WIFI_FLIGHTMODE_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_buffer(&buffer, (uint8*)&address->data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_uint16(&buffer, (uint16)mibFiles->numElements); /* numElements */
+ {
+ int i;
+ for (i = 0; i < mibFiles->numElements; i++)
+ {
+ packedLength += event_pack_uint16(&buffer, mibFiles->datalist[i].length); /*lint !e725 unifi_DataBlock : datalist */
+ packedLength += event_pack_buffer(&buffer, mibFiles->datalist[i].data, mibFiles->datalist[i].length); /*lint !e545 !e725 unifi_DataBlock : datalist */
+ }
+ }
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_set_value_req(uint8** resultBuffer, const unifi_AppValue* appValue)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; appValue->id */
+ /* -----------------------------------------------------------------*/
+ /* A UNION :: unifi_Value_union*/
+ /* -----------------------------------------------------------------*/
+ switch(appValue->id)
+ {
+ case unifi_AdHocConfigValue:
+ /* packedSize += 2; appValue->unifi_Value_union.adHocConfig.atimWindow */
+ /* packedSize += 2; appValue->unifi_Value_union.adHocConfig.beaconPeriod */
+ /* packedSize += 1; appValue->unifi_Value_union.adHocConfig.defaultChannelNumber */
+ packedSize += 5; /* Size of Fixed elements */
+ break;
+ case unifi_CalibrationDataValue:
+ packedSize += appValue->unifi_Value_union.calibrationData.length + 2; /*lint !e725*/ /* unifi_DataBlock :: calibrationData */
+ break;
+ case unifi_CoexConfigValue:
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexEnable */
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexAfhChannelEnable */
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexAdvancedEnable */
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexEnableSchemeManagement */
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexDirection */
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexPeriodicWakeHost */
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexTrafficBurstyLatencyMs */
+ /* packedSize += 2; appValue->unifi_Value_union.coexConfig.coexTrafficContinuousLatencyMs */
+ packedSize += 16; /* Size of Fixed elements */
+ break;
+ case unifi_CoexInfoValue:
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.hasTrafficData */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentTrafficType */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentPeriod */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentPowerSave */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentCoexPeriod */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentCoexLatency */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.hasBtDevice */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.mibValuesSet */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentPeriodicPIOInputOffset */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentPeriodicPIOInputDuration */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentPeriodicPIOInputPeriod */
+ /* packedSize += 2; appValue->unifi_Value_union.coexInfo.currentCoexScheme */
+ packedSize += 24; /* Size of Fixed elements */
+ break;
+ case unifi_ConnectionConfigValue:
+ /* packedSize += 32; appValue->unifi_Value_union.connectionConfig.ssid.ssid */
+ /* packedSize += 1; appValue->unifi_Value_union.connectionConfig.ssid.length */
+ /* packedSize += 6; appValue->unifi_Value_union.connectionConfig.bssid.data */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionConfig.bssType */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionConfig.privacyMode */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionConfig.authMode */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionConfig.encryptionMode */
+ packedSize += appValue->unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length + 2; /*lint !e725*/ /* unifi_DataBlock :: mlmeAssociateReqInformationElements */
+ /* packedSize += 1; appValue->unifi_Value_union.connectionConfig.wmmQosInfo */
+ /* packedSize += 1; appValue->unifi_Value_union.connectionConfig.adhocChannel */
+ packedSize += 49; /* Size of Fixed elements */
+ break;
+ case unifi_ConnectionInfoValue:
+ /* packedSize += 32; appValue->unifi_Value_union.connectionInfo.ssid.ssid */
+ /* packedSize += 1; appValue->unifi_Value_union.connectionInfo.ssid.length */
+ /* packedSize += 6; appValue->unifi_Value_union.connectionInfo.bssid.data */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.networkType80211 */
+ /* packedSize += 1; appValue->unifi_Value_union.connectionInfo.channelNumber */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.channelFrequency */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.authMode */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.ifIndex */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.atimWindow */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.beaconPeriod */
+ packedSize += appValue->unifi_Value_union.connectionInfo.assocScanInfoElements.length + 2; /*lint !e725*/ /* unifi_DataBlock :: assocScanInfoElements */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.assocReqCapabilities */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.assocReqListenInterval */
+ /* packedSize += 6; appValue->unifi_Value_union.connectionInfo.assocReqApAddress.data */
+ packedSize += appValue->unifi_Value_union.connectionInfo.assocReqInfoElements.length + 2; /*lint !e725*/ /* unifi_DataBlock :: assocReqInfoElements */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.assocRspResult */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.assocRspCapabilityInfo */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionInfo.assocRspAssociationId */
+ packedSize += appValue->unifi_Value_union.connectionInfo.assocRspInfoElements.length + 2; /*lint !e725*/ /* unifi_DataBlock :: assocRspInfoElements */
+ packedSize += 68; /* Size of Fixed elements */
+ break;
+ case unifi_ConnectionStatsValue:
+ /* packedSize += 2; appValue->unifi_Value_union.connectionStats.unifiRSSI */
+ /* packedSize += 2; appValue->unifi_Value_union.connectionStats.unifiSNR */
+ /* packedSize += 1; appValue->unifi_Value_union.connectionStats.unifiTxDataRate */
+ /* packedSize += 1; appValue->unifi_Value_union.connectionStats.unifiRxDataRate */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11RetryCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11MultipleRetryCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11ACKFailureCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11FrameDuplicateCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11FCSErrorCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11RTSSuccessCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11RTSFailureCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11ReceivedFragmentCount */
+ /* packedSize += 4; appValue->unifi_Value_union.connectionStats.dot11TransmittedFragmentCount */
+ packedSize += 42; /* Size of Fixed elements */
+ break;
+ case unifi_HostConfigValue:
+ /* packedSize += 2; appValue->unifi_Value_union.hostConfig.powerMode */
+ /* packedSize += 2; appValue->unifi_Value_union.hostConfig.applicationDataPeriodMs */
+ packedSize += 4; /* Size of Fixed elements */
+ break;
+ case unifi_MIBConfigValue:
+ /* packedSize += 2; appValue->unifi_Value_union.mibConfig.unifiFixMaxTxDataRate */
+ /* packedSize += 1; appValue->unifi_Value_union.mibConfig.unifiFixTxDataRate */
+ /* packedSize += 2; appValue->unifi_Value_union.mibConfig.dot11RTSThreshold */
+ /* packedSize += 2; appValue->unifi_Value_union.mibConfig.dot11FragmentationThreshold */
+ /* packedSize += 2; appValue->unifi_Value_union.mibConfig.dot11CurrentTxPowerLevel */
+ packedSize += 9; /* Size of Fixed elements */
+ break;
+ case unifi_PermanentMacAddressValue:
+ /* packedSize += 6; appValue->unifi_Value_union.permanentMacAddress.data */
+ packedSize += 6; /* Size of Fixed elements */
+ break;
+ case unifi_PowerConfigValue:
+ /* packedSize += 2; appValue->unifi_Value_union.powerConfig.powerSaveLevel */
+ /* packedSize += 2; appValue->unifi_Value_union.powerConfig.listenInterval */
+ /* packedSize += 2; appValue->unifi_Value_union.powerConfig.rxDtims */
+ /* packedSize += 2; appValue->unifi_Value_union.powerConfig.d3autoScanMode */
+ packedSize += 8; /* Size of Fixed elements */
+ break;
+ case unifi_RoamingConfigValue:
+ /* packedSize += 66; appValue->unifi_Value_union.roamingConfig.roamingBands */
+ /* packedSize += 1; appValue->unifi_Value_union.roamingConfig.lowQualHystWindow */
+ /* packedSize += 1; appValue->unifi_Value_union.roamingConfig.apBlockTime */
+ /* packedSize += 1; appValue->unifi_Value_union.roamingConfig.roamMonitorPeriod */
+ /* packedSize += 1; appValue->unifi_Value_union.roamingConfig.roamNumMaxTh */
+ packedSize += 70; /* Size of Fixed elements */
+ break;
+ case unifi_SMEConfigValue:
+ /* packedSize += 2; appValue->unifi_Value_union.smeConfig.enablePmkidCanditateListIndications */
+ /* packedSize += 1; appValue->unifi_Value_union.smeConfig.connectionQualityRssiChangeTrigger */
+ /* packedSize += 1; appValue->unifi_Value_union.smeConfig.connectionQualitySnrChangeTrigger */
+ /* packedSize += 2; appValue->unifi_Value_union.smeConfig.trustLevel */
+ /* packedSize += 2; appValue->unifi_Value_union.smeConfig.countryCode */
+ /* packedSize += 2; appValue->unifi_Value_union.smeConfig.wmmMode */
+ /* packedSize += 2; appValue->unifi_Value_union.smeConfig.ifIndex */
+ packedSize += 12; /* Size of Fixed elements */
+ break;
+ case unifi_ScanConfigValue:
+ /* packedSize += 48; appValue->unifi_Value_union.scanControl.scanCfg */
+ /* packedSize += 2; appValue->unifi_Value_union.scanControl.enableIndications */
+ /* packedSize += 2; appValue->unifi_Value_union.scanControl.maxResults */
+ /* packedSize += 1; appValue->unifi_Value_union.scanControl.highRSSIThreshold */
+ /* packedSize += 1; appValue->unifi_Value_union.scanControl.lowRSSIThreshold */
+ /* packedSize += 1; appValue->unifi_Value_union.scanControl.deltaRSSIThreshold */
+ /* packedSize += 1; appValue->unifi_Value_union.scanControl.highSNRThreshold */
+ /* packedSize += 1; appValue->unifi_Value_union.scanControl.lowSNRThreshold */
+ /* packedSize += 1; appValue->unifi_Value_union.scanControl.deltaSNRThreshold */
+ packedSize += appValue->unifi_Value_union.scanControl.passiveChannelList.length + 2; /*lint !e725*/ /* unifi_DataBlock :: passiveChannelList */
+ packedSize += 58; /* Size of Fixed elements */
+ break;
+ case unifi_StationMacAddressValue:
+ /* packedSize += 6; appValue->unifi_Value_union.stationMacAddress.data */
+ packedSize += 6; /* Size of Fixed elements */
+ break;
+ case unifi_VersionsValue:
+ /* packedSize += 4; appValue->unifi_Value_union.versions.chipId */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.chipVersion */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.firmwareBuild */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.firmwareHip */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.driverBuild */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.driverHip */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.driverApi */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.smeBuild */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.smeVariant */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.smeDriverApi */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.smeHip */
+ /* packedSize += 4; appValue->unifi_Value_union.versions.smeSapApi */
+ packedSize += (uint16)osa_strlen(appValue->unifi_Value_union.versions.smeIdString) + 3; /* unifi_String :: smeIdString */
+ packedSize += 48; /* Size of Fixed elements */
+ break;
+ default:
+ break;
+ }
+ /* -----------------------------------------------------------------*/
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_SET_VALUE_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->id); /* id */
+ /* -----------------------------------------------------------------*/
+ /* A UNION :: unifi_Value_union*/
+ /* -----------------------------------------------------------------*/
+ switch(appValue->id)
+ {
+ case unifi_AdHocConfigValue:
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.adHocConfig.atimWindow); /* atimWindow */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.adHocConfig.beaconPeriod); /* beaconPeriod */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.adHocConfig.defaultChannelNumber, 1); /*lint !e545 !e725 defaultChannelNumber */
+ break;
+ case unifi_CalibrationDataValue:
+ packedLength += event_pack_uint16(&buffer, appValue->unifi_Value_union.calibrationData.length); /*lint !e725 unifi_DataBlock : calibrationData */
+ packedLength += event_pack_buffer(&buffer, appValue->unifi_Value_union.calibrationData.data, appValue->unifi_Value_union.calibrationData.length); /*lint !e545 !e725 unifi_DataBlock : calibrationData */
+ break;
+ case unifi_CoexConfigValue:
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexConfig.coexEnable); /* coexEnable */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexConfig.coexAfhChannelEnable); /* coexAfhChannelEnable */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexConfig.coexAdvancedEnable); /* coexAdvancedEnable */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexConfig.coexEnableSchemeManagement); /* coexEnableSchemeManagement */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexConfig.coexDirection); /* coexDirection */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexConfig.coexPeriodicWakeHost); /* coexPeriodicWakeHost */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexConfig.coexTrafficBurstyLatencyMs); /* coexTrafficBurstyLatencyMs */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexConfig.coexTrafficContinuousLatencyMs); /* coexTrafficContinuousLatencyMs */
+ break;
+ case unifi_CoexInfoValue:
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexInfo.hasTrafficData); /* hasTrafficData */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentTrafficType); /* currentTrafficType */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentPeriod); /* currentPeriod */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentPowerSave); /* currentPowerSave */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentCoexPeriod); /* currentCoexPeriod */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentCoexLatency); /* currentCoexLatency */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexInfo.hasBtDevice); /* hasBtDevice */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.coexInfo.mibValuesSet); /* mibValuesSet */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentPeriodicPIOInputOffset); /* currentPeriodicPIOInputOffset */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentPeriodicPIOInputDuration); /* currentPeriodicPIOInputDuration */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentPeriodicPIOInputPeriod); /* currentPeriodicPIOInputPeriod */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.coexInfo.currentCoexScheme); /* currentCoexScheme */
+ break;
+ case unifi_ConnectionConfigValue:
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionConfig.ssid.ssid, 32); /*lint !e545 !e725 ssid */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionConfig.ssid.length, 1); /*lint !e545 !e725 length */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionConfig.bssid.data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionConfig.bssType); /* bssType */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionConfig.privacyMode); /* privacyMode */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionConfig.authMode); /* authMode */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionConfig.encryptionMode); /* encryptionMode */
+ packedLength += event_pack_uint16(&buffer, appValue->unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length); /*lint !e725 unifi_DataBlock : mlmeAssociateReqInformationElements */
+ packedLength += event_pack_buffer(&buffer, appValue->unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.data, appValue->unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length); /*lint !e545 !e725 unifi_DataBlock : mlmeAssociateReqInformationElements */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionConfig.wmmQosInfo, 1); /*lint !e545 !e725 wmmQosInfo */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionConfig.adhocChannel, 1); /*lint !e545 !e725 adhocChannel */
+ break;
+ case unifi_ConnectionInfoValue:
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionInfo.ssid.ssid, 32); /*lint !e545 !e725 ssid */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionInfo.ssid.length, 1); /*lint !e545 !e725 length */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionInfo.bssid.data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.networkType80211); /* networkType80211 */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionInfo.channelNumber, 1); /*lint !e545 !e725 channelNumber */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.channelFrequency); /* channelFrequency */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.authMode); /* authMode */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.ifIndex); /* ifIndex */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.atimWindow); /* atimWindow */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.beaconPeriod); /* beaconPeriod */
+ packedLength += event_pack_uint16(&buffer, appValue->unifi_Value_union.connectionInfo.assocScanInfoElements.length); /*lint !e725 unifi_DataBlock : assocScanInfoElements */
+ packedLength += event_pack_buffer(&buffer, appValue->unifi_Value_union.connectionInfo.assocScanInfoElements.data, appValue->unifi_Value_union.connectionInfo.assocScanInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocScanInfoElements */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.assocReqCapabilities); /* assocReqCapabilities */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.assocReqListenInterval); /* assocReqListenInterval */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionInfo.assocReqApAddress.data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_uint16(&buffer, appValue->unifi_Value_union.connectionInfo.assocReqInfoElements.length); /*lint !e725 unifi_DataBlock : assocReqInfoElements */
+ packedLength += event_pack_buffer(&buffer, appValue->unifi_Value_union.connectionInfo.assocReqInfoElements.data, appValue->unifi_Value_union.connectionInfo.assocReqInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocReqInfoElements */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.assocRspResult); /* assocRspResult */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.assocRspCapabilityInfo); /* assocRspCapabilityInfo */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.connectionInfo.assocRspAssociationId); /* assocRspAssociationId */
+ packedLength += event_pack_uint16(&buffer, appValue->unifi_Value_union.connectionInfo.assocRspInfoElements.length); /*lint !e725 unifi_DataBlock : assocRspInfoElements */
+ packedLength += event_pack_buffer(&buffer, appValue->unifi_Value_union.connectionInfo.assocRspInfoElements.data, appValue->unifi_Value_union.connectionInfo.assocRspInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocRspInfoElements */
+ break;
+ case unifi_ConnectionStatsValue:
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.connectionStats.unifiRSSI); /* unifiRSSI */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.connectionStats.unifiSNR); /* unifiSNR */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionStats.unifiTxDataRate, 1); /*lint !e545 !e725 unifiTxDataRate */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.connectionStats.unifiRxDataRate, 1); /*lint !e545 !e725 unifiRxDataRate */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11RetryCount); /* dot11RetryCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11MultipleRetryCount); /* dot11MultipleRetryCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11ACKFailureCount); /* dot11ACKFailureCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11FrameDuplicateCount); /* dot11FrameDuplicateCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11FCSErrorCount); /* dot11FCSErrorCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11RTSSuccessCount); /* dot11RTSSuccessCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11RTSFailureCount); /* dot11RTSFailureCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11ReceivedFragmentCount); /* dot11ReceivedFragmentCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.connectionStats.dot11TransmittedFragmentCount); /* dot11TransmittedFragmentCount */
+ break;
+ case unifi_HostConfigValue:
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.hostConfig.powerMode); /* powerMode */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.hostConfig.applicationDataPeriodMs); /* applicationDataPeriodMs */
+ break;
+ case unifi_MIBConfigValue:
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.mibConfig.unifiFixMaxTxDataRate); /* unifiFixMaxTxDataRate */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.mibConfig.unifiFixTxDataRate, 1); /*lint !e545 !e725 unifiFixTxDataRate */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.mibConfig.dot11RTSThreshold); /* dot11RTSThreshold */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.mibConfig.dot11FragmentationThreshold); /* dot11FragmentationThreshold */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.mibConfig.dot11CurrentTxPowerLevel); /* dot11CurrentTxPowerLevel */
+ break;
+ case unifi_PermanentMacAddressValue:
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.permanentMacAddress.data, 6); /*lint !e545 !e725 data */
+ break;
+ case unifi_PowerConfigValue:
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.powerConfig.powerSaveLevel); /* powerSaveLevel */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.powerConfig.listenInterval); /* listenInterval */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.powerConfig.rxDtims); /* rxDtims */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.powerConfig.d3autoScanMode); /* d3autoScanMode */
+ break;
+ case unifi_RoamingConfigValue:
+ {
+ int i;
+ for (i = 0; i < 3; i++)
+ {
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.roamingConfig.roamingBands[i].rssiHighThreshold); /* rssiHighThreshold */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.roamingConfig.roamingBands[i].rssiLowThreshold); /* rssiLowThreshold */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.roamingConfig.roamingBands[i].snrHighThreshold); /* snrHighThreshold */
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.roamingConfig.roamingBands[i].snrLowThreshold); /* snrLowThreshold */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.roamingConfig.roamingBands[i].monitorInterval); /* monitorInterval */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.roamingConfig.roamingBands[i].monitorWindow); /* monitorWindow */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamingBands[i].dot11RetryRatio, 1); /*lint !e545 !e725 dot11RetryRatio */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamingBands[i].dot11MultipleRetryRatio, 1); /*lint !e545 !e725 dot11MultipleRetryRatio */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamingBands[i].dot11ACKFailureRatio, 1); /*lint !e545 !e725 dot11ACKFailureRatio */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamingBands[i].dot11FCSErrorRatio, 1); /*lint !e545 !e725 dot11FCSErrorRatio */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamingBands[i].dot11RTSFailureRatio, 1); /*lint !e545 !e725 dot11RTSFailureRatio */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamingBands[i].beaconLossThreshold, 1); /*lint !e545 !e725 beaconLossThreshold */
+ }
+ }
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.lowQualHystWindow, 1); /*lint !e545 !e725 lowQualHystWindow */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.apBlockTime, 1); /*lint !e545 !e725 apBlockTime */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamMonitorPeriod, 1); /*lint !e545 !e725 roamMonitorPeriod */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.roamingConfig.roamNumMaxTh, 1); /*lint !e545 !e725 roamNumMaxTh */
+ break;
+ case unifi_SMEConfigValue:
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.smeConfig.enablePmkidCanditateListIndications); /* enablePmkidCanditateListIndications */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.smeConfig.connectionQualityRssiChangeTrigger, 1); /*lint !e545 !e725 connectionQualityRssiChangeTrigger */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.smeConfig.connectionQualitySnrChangeTrigger, 1); /*lint !e545 !e725 connectionQualitySnrChangeTrigger */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.smeConfig.trustLevel); /* trustLevel */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.smeConfig.countryCode, 2); /*lint !e545 !e725 countryCode */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.smeConfig.wmmMode); /* wmmMode */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.smeConfig.ifIndex); /* ifIndex */
+ break;
+ case unifi_ScanConfigValue:
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.scanControl.scanCfg[i].interval); /* interval */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.scanControl.scanCfg[i].validity); /* validity */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.scanControl.scanCfg[i].minActiveChannelTime); /* minActiveChannelTime */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.scanControl.scanCfg[i].maxActiveChannelTime); /* maxActiveChannelTime */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.scanControl.scanCfg[i].minPassiveChannelTime); /* minPassiveChannelTime */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.scanControl.scanCfg[i].maxPassiveChannelTime); /* maxPassiveChannelTime */
+ }
+ }
+ packedLength += event_pack_int16(&buffer, (int16)appValue->unifi_Value_union.scanControl.enableIndications); /* enableIndications */
+ packedLength += event_pack_uint16(&buffer, (uint16)appValue->unifi_Value_union.scanControl.maxResults); /* maxResults */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.scanControl.highRSSIThreshold, 1); /*lint !e545 !e725 highRSSIThreshold */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.scanControl.lowRSSIThreshold, 1); /*lint !e545 !e725 lowRSSIThreshold */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.scanControl.deltaRSSIThreshold, 1); /*lint !e545 !e725 deltaRSSIThreshold */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.scanControl.highSNRThreshold, 1); /*lint !e545 !e725 highSNRThreshold */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.scanControl.lowSNRThreshold, 1); /*lint !e545 !e725 lowSNRThreshold */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.scanControl.deltaSNRThreshold, 1); /*lint !e545 !e725 deltaSNRThreshold */
+ packedLength += event_pack_uint16(&buffer, appValue->unifi_Value_union.scanControl.passiveChannelList.length); /*lint !e725 unifi_DataBlock : passiveChannelList */
+ packedLength += event_pack_buffer(&buffer, appValue->unifi_Value_union.scanControl.passiveChannelList.data, appValue->unifi_Value_union.scanControl.passiveChannelList.length); /*lint !e545 !e725 unifi_DataBlock : passiveChannelList */
+ break;
+ case unifi_StationMacAddressValue:
+ packedLength += event_pack_buffer(&buffer, (uint8*)&appValue->unifi_Value_union.stationMacAddress.data, 6); /*lint !e545 !e725 data */
+ break;
+ case unifi_VersionsValue:
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.chipId); /* chipId */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.chipVersion); /* chipVersion */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.firmwareBuild); /* firmwareBuild */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.firmwareHip); /* firmwareHip */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.driverBuild); /* driverBuild */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.driverHip); /* driverHip */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.driverApi); /* driverApi */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.smeBuild); /* smeBuild */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.smeVariant); /* smeVariant */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.smeDriverApi); /* smeDriverApi */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.smeHip); /* smeHip */
+ packedLength += event_pack_uint32(&buffer, (uint32)appValue->unifi_Value_union.versions.smeSapApi); /* smeSapApi */
+ packedLength += event_pack_string(&buffer, appValue->unifi_Value_union.versions.smeIdString); /* unifi_String : smeIdString */
+ break;
+ default:
+ break;
+ }
+ /* -----------------------------------------------------------------*/
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_get_value_req(uint8** resultBuffer, unifi_AppValueId appValueId)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; appValueId */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_GET_VALUE_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)appValueId); /* appValueId */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_mib_set_req(uint8** resultBuffer, const unifi_DataBlock* mibAttribute)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ packedSize += mibAttribute->length + 2; /*lint !e725*/ /* unifi_DataBlock :: mibAttribute */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_MIB_SET_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, mibAttribute->length); /*lint !e725 unifi_DataBlock : mibAttribute */
+ packedLength += event_pack_buffer(&buffer, mibAttribute->data, mibAttribute->length); /*lint !e545 !e725 unifi_DataBlock : mibAttribute */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_mib_get_req(uint8** resultBuffer, const unifi_DataBlock* mibAttribute)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ packedSize += mibAttribute->length + 2; /*lint !e725*/ /* unifi_DataBlock :: mibAttribute */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_MIB_GET_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, mibAttribute->length); /*lint !e725 unifi_DataBlock : mibAttribute */
+ packedLength += event_pack_buffer(&buffer, mibAttribute->data, mibAttribute->length); /*lint !e545 !e725 unifi_DataBlock : mibAttribute */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_mib_get_next_req(uint8** resultBuffer, const unifi_DataBlock* mibAttribute)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ packedSize += mibAttribute->length + 2; /*lint !e725*/ /* unifi_DataBlock :: mibAttribute */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_MIB_GET_NEXT_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, mibAttribute->length); /*lint !e725 unifi_DataBlock : mibAttribute */
+ packedLength += event_pack_buffer(&buffer, mibAttribute->data, mibAttribute->length); /*lint !e545 !e725 unifi_DataBlock : mibAttribute */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_scan_full_req(uint8** resultBuffer, const unifi_SSID* ssid, Boolean forceScan, unifi_ScanType scanType, const unifi_DataBlock* channelList)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 32; ssid->ssid */
+ /* packedSize += 1; ssid->length */
+ /* packedSize += 2; forceScan */
+ /* packedSize += 2; scanType */
+ packedSize += channelList->length + 2; /*lint !e725*/ /* unifi_DataBlock :: channelList */
+ packedSize += 37; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_SCAN_FULL_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_buffer(&buffer, (uint8*)&ssid->ssid, 32); /*lint !e545 !e725 ssid */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&ssid->length, 1); /*lint !e545 !e725 length */
+ packedLength += event_pack_int16(&buffer, (int16)forceScan); /* forceScan */
+ packedLength += event_pack_uint16(&buffer, (uint16)scanType); /* scanType */
+ packedLength += event_pack_uint16(&buffer, channelList->length); /*lint !e725 unifi_DataBlock : channelList */
+ packedLength += event_pack_buffer(&buffer, channelList->data, channelList->length); /*lint !e545 !e725 unifi_DataBlock : channelList */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_scan_results_get_req(uint8** resultBuffer)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_SCAN_RESULTS_GET_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_connect_req(uint8** resultBuffer, const unifi_ConnectionConfig* connectionConfig)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 32; connectionConfig->ssid.ssid */
+ /* packedSize += 1; connectionConfig->ssid.length */
+ /* packedSize += 6; connectionConfig->bssid.data */
+ /* packedSize += 2; connectionConfig->bssType */
+ /* packedSize += 2; connectionConfig->privacyMode */
+ /* packedSize += 2; connectionConfig->authMode */
+ /* packedSize += 2; connectionConfig->encryptionMode */
+ packedSize += connectionConfig->mlmeAssociateReqInformationElements.length + 2; /*lint !e725*/ /* unifi_DataBlock :: mlmeAssociateReqInformationElements */
+ /* packedSize += 1; connectionConfig->wmmQosInfo */
+ /* packedSize += 1; connectionConfig->adhocChannel */
+ packedSize += 49; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_CONNECT_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_buffer(&buffer, (uint8*)&connectionConfig->ssid.ssid, 32); /*lint !e545 !e725 ssid */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&connectionConfig->ssid.length, 1); /*lint !e545 !e725 length */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&connectionConfig->bssid.data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_uint16(&buffer, (uint16)connectionConfig->bssType); /* bssType */
+ packedLength += event_pack_uint16(&buffer, (uint16)connectionConfig->privacyMode); /* privacyMode */
+ packedLength += event_pack_uint16(&buffer, (uint16)connectionConfig->authMode); /* authMode */
+ packedLength += event_pack_uint16(&buffer, (uint16)connectionConfig->encryptionMode); /* encryptionMode */
+ packedLength += event_pack_uint16(&buffer, connectionConfig->mlmeAssociateReqInformationElements.length); /*lint !e725 unifi_DataBlock : mlmeAssociateReqInformationElements */
+ packedLength += event_pack_buffer(&buffer, connectionConfig->mlmeAssociateReqInformationElements.data, connectionConfig->mlmeAssociateReqInformationElements.length); /*lint !e545 !e725 unifi_DataBlock : mlmeAssociateReqInformationElements */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&connectionConfig->wmmQosInfo, 1); /*lint !e545 !e725 wmmQosInfo */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&connectionConfig->adhocChannel, 1); /*lint !e545 !e725 adhocChannel */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_disconnect_req(uint8** resultBuffer)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_DISCONNECT_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_multicast_address_req(uint8** resultBuffer, unifi_ListAction action, const unifi_MulticastAddressList* setAddresses)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; action */
+ /* packedSize += 1; setAddresses->numElements */
+ {
+ int i;
+ for (i = 0; i < setAddresses->numElements; i++)
+ {
+ /* packedSize += 6; setAddresses->addresses[i].data */
+ packedSize += 6;
+ }
+ }
+ packedSize += 3; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_MULTICAST_ADDRESS_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)action); /* action */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&setAddresses->numElements, 1); /*lint !e545 !e725 numElements */
+ {
+ int i;
+ for (i = 0; i < setAddresses->numElements; i++)
+ {
+ packedLength += event_pack_buffer(&buffer, (uint8*)&setAddresses->addresses[i].data, 6); /*lint !e545 !e725 data */
+ }
+ }
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_pmkid_req(uint8** resultBuffer, unifi_ListAction action, const unifi_PmkidList* setPmkidList)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; action */
+ /* packedSize += 1; setPmkidList->numElements */
+ {
+ int i;
+ for (i = 0; i < setPmkidList->numElements; i++)
+ {
+ /* packedSize += 6; setPmkidList->pmkids[i].bssid.data */
+ /* packedSize += 16; setPmkidList->pmkids[i].pmkid */
+ packedSize += 22;
+ }
+ }
+ packedSize += 3; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_PMKID_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)action); /* action */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&setPmkidList->numElements, 1); /*lint !e545 !e725 numElements */
+ {
+ int i;
+ for (i = 0; i < setPmkidList->numElements; i++)
+ {
+ packedLength += event_pack_buffer(&buffer, (uint8*)&setPmkidList->pmkids[i].bssid.data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&setPmkidList->pmkids[i].pmkid, 16); /*lint !e545 !e725 pmkid */
+ }
+ }
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_key_req(uint8** resultBuffer, unifi_ListAction action, const unifi_Key* key)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; action */
+ /* packedSize += 2; key->keyType */
+ /* packedSize += 1; key->keyIndex */
+ /* packedSize += 2; key->wepTxKey */
+ /* packedSize += 8; key->keyRsc.data */
+ /* packedSize += 2; key->authenticator */
+ /* packedSize += 6; key->address.data */
+ /* packedSize += 1; key->keyLength */
+ /* packedSize += 32; key->key */
+ packedSize += 56; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_KEY_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)action); /* action */
+ packedLength += event_pack_uint16(&buffer, (uint16)key->keyType); /* keyType */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&key->keyIndex, 1); /*lint !e545 !e725 keyIndex */
+ packedLength += event_pack_int16(&buffer, (int16)key->wepTxKey); /* wepTxKey */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&key->keyRsc.data, 8); /*lint !e545 !e725 data */
+ packedLength += event_pack_int16(&buffer, (int16)key->authenticator); /* authenticator */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&key->address.data, 6); /*lint !e545 !e725 data */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&key->keyLength, 1); /*lint !e545 !e725 keyLength */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&key->key, 32); /*lint !e545 !e725 key */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_packet_filter_set_req(uint8** resultBuffer, const unifi_DataBlock* filter, unifi_PacketFilterMode mode, unifi_IPV4Address arpFilterAddress)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ packedSize += filter->length + 2; /*lint !e725*/ /* unifi_DataBlock :: filter */
+ /* packedSize += 2; mode */
+ /* packedSize += 4; arpFilterAddress */
+ packedSize += 6; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_PACKET_FILTER_SET_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, filter->length); /*lint !e725 unifi_DataBlock : filter */
+ packedLength += event_pack_buffer(&buffer, filter->data, filter->length); /*lint !e545 !e725 unifi_DataBlock : filter */
+ packedLength += event_pack_uint16(&buffer, (uint16)mode); /* mode */
+ packedLength += event_pack_uint32(&buffer, (uint32)arpFilterAddress); /* arpFilterAddress */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_mgt_tspec_req(uint8** resultBuffer, unifi_ListAction action, uint32 transactionId, Boolean strict, const unifi_DataBlock* tspec, const unifi_DataBlock* tclas)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; action */
+ /* packedSize += 4; transactionId */
+ /* packedSize += 2; strict */
+ packedSize += tspec->length + 2; /*lint !e725*/ /* unifi_DataBlock :: tspec */
+ packedSize += tclas->length + 2; /*lint !e725*/ /* unifi_DataBlock :: tclas */
+ packedSize += 8; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_MGT_TSPEC_REQ_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)action); /* action */
+ packedLength += event_pack_uint32(&buffer, (uint32)transactionId); /* transactionId */
+ packedLength += event_pack_int16(&buffer, (int16)strict); /* strict */
+ packedLength += event_pack_uint16(&buffer, tspec->length); /*lint !e725 unifi_DataBlock : tspec */
+ packedLength += event_pack_buffer(&buffer, tspec->data, tspec->length); /*lint !e545 !e725 unifi_DataBlock : tspec */
+ packedLength += event_pack_uint16(&buffer, tclas->length); /*lint !e725 unifi_DataBlock : tclas */
+ packedLength += event_pack_buffer(&buffer, tclas->data, tclas->length); /*lint !e545 !e725 unifi_DataBlock : tclas */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.h
new file mode 100644
index 0000000..4ecf222
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_build_functions.h
@@ -0,0 +1,42 @@
+/* This is an autogenerated file from sme__build_signal_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MGT_BUILD_FUNCTIONS_H__
+#define __MGT_BUILD_FUNCTIONS_H__
+
+#include "fsm/fsm.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "smeio/smeio_fsm_events.h"
+
+extern uint16 build_packed_unifi_mgt_wifi_on_req(uint8** resultBuffer, const unifi_MACAddress* address, const unifi_DataBlockList* mibFiles);
+extern uint16 build_packed_unifi_mgt_wifi_off_req(uint8** resultBuffer);
+extern uint16 build_packed_unifi_mgt_wifi_flightmode_req(uint8** resultBuffer, const unifi_MACAddress* address, const unifi_DataBlockList* mibFiles);
+extern uint16 build_packed_unifi_mgt_set_value_req(uint8** resultBuffer, const unifi_AppValue* appValue);
+extern uint16 build_packed_unifi_mgt_get_value_req(uint8** resultBuffer, unifi_AppValueId appValueId);
+extern uint16 build_packed_unifi_mgt_mib_set_req(uint8** resultBuffer, const unifi_DataBlock* mibAttribute);
+extern uint16 build_packed_unifi_mgt_mib_get_req(uint8** resultBuffer, const unifi_DataBlock* mibAttribute);
+extern uint16 build_packed_unifi_mgt_mib_get_next_req(uint8** resultBuffer, const unifi_DataBlock* mibAttribute);
+extern uint16 build_packed_unifi_mgt_scan_full_req(uint8** resultBuffer, const unifi_SSID* ssid, Boolean forceScan, unifi_ScanType scanType, const unifi_DataBlock* channelList);
+extern uint16 build_packed_unifi_mgt_scan_results_get_req(uint8** resultBuffer);
+extern uint16 build_packed_unifi_mgt_connect_req(uint8** resultBuffer, const unifi_ConnectionConfig* connectionConfig);
+extern uint16 build_packed_unifi_mgt_disconnect_req(uint8** resultBuffer);
+extern uint16 build_packed_unifi_mgt_multicast_address_req(uint8** resultBuffer, unifi_ListAction action, const unifi_MulticastAddressList* setAddresses);
+extern uint16 build_packed_unifi_mgt_pmkid_req(uint8** resultBuffer, unifi_ListAction action, const unifi_PmkidList* setPmkidList);
+extern uint16 build_packed_unifi_mgt_key_req(uint8** resultBuffer, unifi_ListAction action, const unifi_Key* key);
+extern uint16 build_packed_unifi_mgt_packet_filter_set_req(uint8** resultBuffer, const unifi_DataBlock* filter, unifi_PacketFilterMode mode, unifi_IPV4Address arpFilterAddress);
+extern uint16 build_packed_unifi_mgt_tspec_req(uint8** resultBuffer, unifi_ListAction action, uint32 transactionId, Boolean strict, const unifi_DataBlock* tspec, const unifi_DataBlock* tclas);
+
+
+#endif /* __MGT_BUILD_FUNCTIONS_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_remoteserver_to_sme_interface.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_remoteserver_to_sme_interface.c
new file mode 100644
index 0000000..e2ac3d0
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/mgt_sap/mgt_sap_remoteserver_to_sme_interface.c
@@ -0,0 +1,1074 @@
+/* This is an autogenerated file from sme__remote_client_interface_c */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+/* This is an autogenerated file from sme__remote_client_interface_c.pl */
+
+
+#include "fsm/fsm.h"
+#include "fsm/fsm_types.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "smeio/smeio_fsm_events.h"
+#include "event_pack_unpack/event_pack_unpack.h"
+#include "mgt_sap/mgt_sap.h"
+#include "mgt_sap/mgt_sap_remote_sme_interface.h"
+
+static void event_to_unifi_mgt_wifi_on_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtWifiOnCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_wifi_on_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_wifi_off_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtWifiOffCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_wifi_off_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_wifi_off_ind(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtWifiOffInd_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.controlIndication = event_unpack_uint16(&buffer); /* unifi_ControlIndication : controlIndication */
+
+ unifi_mgt_wifi_off_ind(context, evt.controlIndication);
+
+}
+
+static void event_to_unifi_mgt_wifi_flightmode_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtWifiFlightmodeCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_wifi_flightmode_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_set_value_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtSetValueCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.appValueId = event_unpack_uint16(&buffer); /* unifi_AppValueId : appValueId */
+
+ unifi_mgt_set_value_cfm(context, evt.status, evt.appValueId);
+
+}
+
+static void event_to_unifi_mgt_get_value_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtGetValueCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.appValue.id = event_unpack_uint16(&buffer); /* unifi_AppValueId : id */
+ /* -----------------------------------------------------------------*/
+ /* A UNION :: unifi_Value_union*/
+ /* -----------------------------------------------------------------*/
+ switch(evt.appValue.id)
+ {
+ case unifi_AdHocConfigValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.adHocConfig.atimWindow = event_unpack_uint16(&buffer); /* uint16 : atimWindow */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.adHocConfig.beaconPeriod = event_unpack_uint16(&buffer); /* uint16 : beaconPeriod */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.adHocConfig.defaultChannelNumber = event_unpack_uint8(&buffer); /* uint8 : defaultChannelNumber */
+ break;
+ case unifi_CalibrationDataValue:
+ evt.appValue.unifi_Value_union.calibrationData.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : calibrationData */
+ evt.appValue.unifi_Value_union.calibrationData.data = NULL;
+ if (evt.appValue.unifi_Value_union.calibrationData.length)
+ {
+ evt.appValue.unifi_Value_union.calibrationData.data = (uint8*)osa_malloc(evt.appValue.unifi_Value_union.calibrationData.length); /*lint !e725 unifi_DataBlock : calibrationData*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.appValue.unifi_Value_union.calibrationData.data, evt.appValue.unifi_Value_union.calibrationData.length); /*lint !e545 !e725 unifi_DataBlock : calibrationData */
+ }
+ break;
+ case unifi_CoexConfigValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexEnable = event_unpack_int16(&buffer); /* Boolean : coexEnable */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexAfhChannelEnable = event_unpack_int16(&buffer); /* Boolean : coexAfhChannelEnable */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexAdvancedEnable = event_unpack_int16(&buffer); /* Boolean : coexAdvancedEnable */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexEnableSchemeManagement = event_unpack_int16(&buffer); /* Boolean : coexEnableSchemeManagement */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexDirection = event_unpack_uint16(&buffer); /* unifi_CoexDirection : coexDirection */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexPeriodicWakeHost = event_unpack_int16(&buffer); /* Boolean : coexPeriodicWakeHost */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexTrafficBurstyLatencyMs = event_unpack_uint16(&buffer); /* uint16 : coexTrafficBurstyLatencyMs */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexConfig.coexTrafficContinuousLatencyMs = event_unpack_uint16(&buffer); /* uint16 : coexTrafficContinuousLatencyMs */
+ break;
+ case unifi_CoexInfoValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.hasTrafficData = event_unpack_int16(&buffer); /* Boolean : hasTrafficData */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentTrafficType = event_unpack_uint16(&buffer); /* unifi_traffic_type : currentTrafficType */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentPeriod = event_unpack_uint16(&buffer); /* uint16 : currentPeriod */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentPowerSave = event_unpack_uint16(&buffer); /* unifi_PowerSaveLevel : currentPowerSave */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentCoexPeriod = event_unpack_uint16(&buffer); /* uint16 : currentCoexPeriod */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentCoexLatency = event_unpack_uint16(&buffer); /* uint16 : currentCoexLatency */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.hasBtDevice = event_unpack_int16(&buffer); /* Boolean : hasBtDevice */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.mibValuesSet = event_unpack_int16(&buffer); /* Boolean : mibValuesSet */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentPeriodicPIOInputOffset = event_unpack_uint16(&buffer); /* uint16 : currentPeriodicPIOInputOffset */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentPeriodicPIOInputDuration = event_unpack_uint16(&buffer); /* uint16 : currentPeriodicPIOInputDuration */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentPeriodicPIOInputPeriod = event_unpack_uint16(&buffer); /* uint16 : currentPeriodicPIOInputPeriod */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.coexInfo.currentCoexScheme = event_unpack_uint16(&buffer); /* unifi_CoexScheme : currentCoexScheme */
+ break;
+ case unifi_ConnectionConfigValue:
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.connectionConfig.ssid.ssid, 32); /*lint !e545 !e725 uint8 : ssid */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionConfig.ssid.length = event_unpack_uint8(&buffer); /* uint8 : length */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.connectionConfig.bssid.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionConfig.bssType = event_unpack_uint16(&buffer); /* unifi_BSSType : bssType */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionConfig.privacyMode = event_unpack_uint16(&buffer); /* unifi_80211_PrivacyMode : privacyMode */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionConfig.authMode = event_unpack_uint16(&buffer); /* uint16 : authMode */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionConfig.encryptionMode = event_unpack_uint16(&buffer); /* uint16 : encryptionMode */
+ evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : mlmeAssociateReqInformationElements */
+ evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.data = NULL;
+ if (evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length)
+ {
+ evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.data = (uint8*)osa_malloc(evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length); /*lint !e725 unifi_DataBlock : mlmeAssociateReqInformationElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.data, evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length); /*lint !e545 !e725 unifi_DataBlock : mlmeAssociateReqInformationElements */
+ }
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionConfig.wmmQosInfo = event_unpack_uint8(&buffer); /* uint8 : wmmQosInfo */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionConfig.adhocChannel = event_unpack_uint8(&buffer); /* uint8 : adhocChannel */
+ break;
+ case unifi_ConnectionInfoValue:
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.connectionInfo.ssid.ssid, 32); /*lint !e545 !e725 uint8 : ssid */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.ssid.length = event_unpack_uint8(&buffer); /* uint8 : length */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.connectionInfo.bssid.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.networkType80211 = event_unpack_uint16(&buffer); /* unifi_80211_NetworkType : networkType80211 */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.channelNumber = event_unpack_uint8(&buffer); /* uint8 : channelNumber */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.channelFrequency = event_unpack_uint16(&buffer); /* uint16 : channelFrequency */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.authMode = event_unpack_uint16(&buffer); /* unifi_AuthMode : authMode */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.ifIndex = event_unpack_uint16(&buffer); /* unifi_RadioIF : ifIndex */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.atimWindow = event_unpack_uint16(&buffer); /* uint16 : atimWindow */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.beaconPeriod = event_unpack_uint16(&buffer); /* uint16 : beaconPeriod */
+ evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : assocScanInfoElements */
+ evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.data = NULL;
+ if (evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.length)
+ {
+ evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.data = (uint8*)osa_malloc(evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.length); /*lint !e725 unifi_DataBlock : assocScanInfoElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.data, evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocScanInfoElements */
+ }
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.assocReqCapabilities = event_unpack_uint16(&buffer); /* uint16 : assocReqCapabilities */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.assocReqListenInterval = event_unpack_uint16(&buffer); /* uint16 : assocReqListenInterval */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.connectionInfo.assocReqApAddress.data, 6); /*lint !e545 !e725 uint8 : data */
+ evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : assocReqInfoElements */
+ evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.data = NULL;
+ if (evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.length)
+ {
+ evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.data = (uint8*)osa_malloc(evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.length); /*lint !e725 unifi_DataBlock : assocReqInfoElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.data, evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocReqInfoElements */
+ }
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.assocRspResult = event_unpack_uint16(&buffer); /* unifi_IEEE80211_Result : assocRspResult */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.assocRspCapabilityInfo = event_unpack_uint16(&buffer); /* uint16 : assocRspCapabilityInfo */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionInfo.assocRspAssociationId = event_unpack_uint16(&buffer); /* uint16 : assocRspAssociationId */
+ evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : assocRspInfoElements */
+ evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.data = NULL;
+ if (evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.length)
+ {
+ evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.data = (uint8*)osa_malloc(evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.length); /*lint !e725 unifi_DataBlock : assocRspInfoElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.data, evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocRspInfoElements */
+ }
+ break;
+ case unifi_ConnectionStatsValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.unifiRSSI = event_unpack_int16(&buffer); /* int16 : unifiRSSI */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.unifiSNR = event_unpack_int16(&buffer); /* int16 : unifiSNR */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.unifiTxDataRate = event_unpack_uint8(&buffer); /* uint8 : unifiTxDataRate */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.unifiRxDataRate = event_unpack_uint8(&buffer); /* uint8 : unifiRxDataRate */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11RetryCount = event_unpack_uint32(&buffer); /* uint32 : dot11RetryCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11MultipleRetryCount = event_unpack_uint32(&buffer); /* uint32 : dot11MultipleRetryCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11ACKFailureCount = event_unpack_uint32(&buffer); /* uint32 : dot11ACKFailureCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11FrameDuplicateCount = event_unpack_uint32(&buffer); /* uint32 : dot11FrameDuplicateCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11FCSErrorCount = event_unpack_uint32(&buffer); /* uint32 : dot11FCSErrorCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11RTSSuccessCount = event_unpack_uint32(&buffer); /* uint32 : dot11RTSSuccessCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11RTSFailureCount = event_unpack_uint32(&buffer); /* uint32 : dot11RTSFailureCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11ReceivedFragmentCount = event_unpack_uint32(&buffer); /* uint32 : dot11ReceivedFragmentCount */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.connectionStats.dot11TransmittedFragmentCount = event_unpack_uint32(&buffer); /* uint32 : dot11TransmittedFragmentCount */
+ break;
+ case unifi_HostConfigValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.hostConfig.powerMode = event_unpack_uint16(&buffer); /* unifi_HostPowerMode : powerMode */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.hostConfig.applicationDataPeriodMs = event_unpack_uint16(&buffer); /* uint16 : applicationDataPeriodMs */
+ break;
+ case unifi_MIBConfigValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.mibConfig.unifiFixMaxTxDataRate = event_unpack_int16(&buffer); /* Boolean : unifiFixMaxTxDataRate */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.mibConfig.unifiFixTxDataRate = event_unpack_uint8(&buffer); /* uint8 : unifiFixTxDataRate */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.mibConfig.dot11RTSThreshold = event_unpack_uint16(&buffer); /* uint16 : dot11RTSThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.mibConfig.dot11FragmentationThreshold = event_unpack_uint16(&buffer); /* uint16 : dot11FragmentationThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.mibConfig.dot11CurrentTxPowerLevel = event_unpack_uint16(&buffer); /* uint16 : dot11CurrentTxPowerLevel */
+ break;
+ case unifi_PermanentMacAddressValue:
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.permanentMacAddress.data, 6); /*lint !e545 !e725 uint8 : data */
+ break;
+ case unifi_PowerConfigValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.powerConfig.powerSaveLevel = event_unpack_uint16(&buffer); /* unifi_PowerSaveLevel : powerSaveLevel */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.powerConfig.listenInterval = event_unpack_uint16(&buffer); /* uint16 : listenInterval */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.powerConfig.rxDtims = event_unpack_int16(&buffer); /* Boolean : rxDtims */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.powerConfig.d3autoScanMode = event_unpack_uint16(&buffer); /* unifi_D3AutoScanMode : d3autoScanMode */
+ break;
+ case unifi_RoamingConfigValue:
+ {
+ int i;
+ for (i = 0; i < 3; i++)
+ {
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].rssiHighThreshold = event_unpack_int16(&buffer); /* int16 : rssiHighThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].rssiLowThreshold = event_unpack_int16(&buffer); /* int16 : rssiLowThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].snrHighThreshold = event_unpack_int16(&buffer); /* int16 : snrHighThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].snrLowThreshold = event_unpack_int16(&buffer); /* int16 : snrLowThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].monitorInterval = event_unpack_uint32(&buffer); /* uint32 : monitorInterval */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].monitorWindow = event_unpack_uint32(&buffer); /* uint32 : monitorWindow */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].dot11RetryRatio = event_unpack_uint8(&buffer); /* uint8 : dot11RetryRatio */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].dot11MultipleRetryRatio = event_unpack_uint8(&buffer); /* uint8 : dot11MultipleRetryRatio */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].dot11ACKFailureRatio = event_unpack_uint8(&buffer); /* uint8 : dot11ACKFailureRatio */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].dot11FCSErrorRatio = event_unpack_uint8(&buffer); /* uint8 : dot11FCSErrorRatio */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].dot11RTSFailureRatio = event_unpack_uint8(&buffer); /* uint8 : dot11RTSFailureRatio */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamingBands[i].beaconLossThreshold = event_unpack_uint8(&buffer); /* uint8 : beaconLossThreshold */
+ }
+ }
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.lowQualHystWindow = event_unpack_uint8(&buffer); /* uint8 : lowQualHystWindow */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.apBlockTime = event_unpack_uint8(&buffer); /* uint8 : apBlockTime */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamMonitorPeriod = event_unpack_uint8(&buffer); /* uint8 : roamMonitorPeriod */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.roamingConfig.roamNumMaxTh = event_unpack_uint8(&buffer); /* uint8 : roamNumMaxTh */
+ break;
+ case unifi_SMEConfigValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.smeConfig.enablePmkidCanditateListIndications = event_unpack_int16(&buffer); /* Boolean : enablePmkidCanditateListIndications */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.smeConfig.connectionQualityRssiChangeTrigger = event_unpack_uint8(&buffer); /* uint8 : connectionQualityRssiChangeTrigger */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.smeConfig.connectionQualitySnrChangeTrigger = event_unpack_uint8(&buffer); /* uint8 : connectionQualitySnrChangeTrigger */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.smeConfig.trustLevel = event_unpack_uint16(&buffer); /* unifi_80211dTrustLevel : trustLevel */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.smeConfig.countryCode, 2); /*lint !e545 !e725 uint8 : countryCode */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.smeConfig.wmmMode = event_unpack_uint16(&buffer); /* uint16 : wmmMode */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.smeConfig.ifIndex = event_unpack_uint16(&buffer); /* unifi_RadioIF : ifIndex */
+ break;
+ case unifi_ScanConfigValue:
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.scanCfg[i].interval = event_unpack_uint16(&buffer); /* uint16 : interval */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.scanCfg[i].validity = event_unpack_uint16(&buffer); /* uint16 : validity */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.scanCfg[i].minActiveChannelTime = event_unpack_uint16(&buffer); /* uint16 : minActiveChannelTime */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.scanCfg[i].maxActiveChannelTime = event_unpack_uint16(&buffer); /* uint16 : maxActiveChannelTime */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.scanCfg[i].minPassiveChannelTime = event_unpack_uint16(&buffer); /* uint16 : minPassiveChannelTime */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.scanCfg[i].maxPassiveChannelTime = event_unpack_uint16(&buffer); /* uint16 : maxPassiveChannelTime */
+ }
+ }
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.enableIndications = event_unpack_int16(&buffer); /* Boolean : enableIndications */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.maxResults = event_unpack_uint16(&buffer); /* uint16 : maxResults */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.highRSSIThreshold = event_unpack_int8(&buffer); /* int8 : highRSSIThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.lowRSSIThreshold = event_unpack_int8(&buffer); /* int8 : lowRSSIThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.deltaRSSIThreshold = event_unpack_int8(&buffer); /* int8 : deltaRSSIThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.highSNRThreshold = event_unpack_int8(&buffer); /* int8 : highSNRThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.lowSNRThreshold = event_unpack_int8(&buffer); /* int8 : lowSNRThreshold */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.scanControl.deltaSNRThreshold = event_unpack_int8(&buffer); /* int8 : deltaSNRThreshold */
+ evt.appValue.unifi_Value_union.scanControl.passiveChannelList.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : passiveChannelList */
+ evt.appValue.unifi_Value_union.scanControl.passiveChannelList.data = NULL;
+ if (evt.appValue.unifi_Value_union.scanControl.passiveChannelList.length)
+ {
+ evt.appValue.unifi_Value_union.scanControl.passiveChannelList.data = (uint8*)osa_malloc(evt.appValue.unifi_Value_union.scanControl.passiveChannelList.length); /*lint !e725 unifi_DataBlock : passiveChannelList*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.appValue.unifi_Value_union.scanControl.passiveChannelList.data, evt.appValue.unifi_Value_union.scanControl.passiveChannelList.length); /*lint !e545 !e725 unifi_DataBlock : passiveChannelList */
+ }
+ break;
+ case unifi_StationMacAddressValue:
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.appValue.unifi_Value_union.stationMacAddress.data, 6); /*lint !e545 !e725 uint8 : data */
+ break;
+ case unifi_VersionsValue:
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.chipId = event_unpack_uint32(&buffer); /* uint32 : chipId */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.chipVersion = event_unpack_uint32(&buffer); /* uint32 : chipVersion */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.firmwareBuild = event_unpack_uint32(&buffer); /* uint32 : firmwareBuild */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.firmwareHip = event_unpack_uint32(&buffer); /* uint32 : firmwareHip */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.driverBuild = event_unpack_uint32(&buffer); /* uint32 : driverBuild */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.driverHip = event_unpack_uint32(&buffer); /* uint32 : driverHip */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.driverApi = event_unpack_uint32(&buffer); /* uint32 : driverApi */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.smeBuild = event_unpack_uint32(&buffer); /* uint32 : smeBuild */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.smeVariant = event_unpack_uint32(&buffer); /* uint32 : smeVariant */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.smeDriverApi = event_unpack_uint32(&buffer); /* uint32 : smeDriverApi */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.smeHip = event_unpack_uint32(&buffer); /* uint32 : smeHip */
+ /*lint -save -e545 -e725 */
+ evt.appValue.unifi_Value_union.versions.smeSapApi = event_unpack_uint32(&buffer); /* uint32 : smeSapApi */
+ evt.appValue.unifi_Value_union.versions.smeIdString = event_unpack_string(&buffer); /* unifi_String : smeIdString */
+ break;
+ default:
+ break;
+ }
+ /* -----------------------------------------------------------------*/
+
+ unifi_mgt_get_value_cfm(context, evt.status, &evt.appValue);
+
+ /* -----------------------------------------------------------------*/
+ /* A UNION :: unifi_Value_union*/
+ /* -----------------------------------------------------------------*/
+ switch(evt.appValue.id)
+ {
+ case unifi_AdHocConfigValue:
+ break;
+ case unifi_CalibrationDataValue:
+ if (evt.appValue.unifi_Value_union.calibrationData.length)
+ {
+ osa_free(evt.appValue.unifi_Value_union.calibrationData.data); /*lint !e725 unifi_DataBlock : calibrationData*/
+ }
+ break;
+ case unifi_CoexConfigValue:
+ break;
+ case unifi_CoexInfoValue:
+ break;
+ case unifi_ConnectionConfigValue:
+ if (evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.length)
+ {
+ osa_free(evt.appValue.unifi_Value_union.connectionConfig.mlmeAssociateReqInformationElements.data); /*lint !e725 unifi_DataBlock : mlmeAssociateReqInformationElements*/
+ }
+ break;
+ case unifi_ConnectionInfoValue:
+ if (evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.length)
+ {
+ osa_free(evt.appValue.unifi_Value_union.connectionInfo.assocScanInfoElements.data); /*lint !e725 unifi_DataBlock : assocScanInfoElements*/
+ }
+ if (evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.length)
+ {
+ osa_free(evt.appValue.unifi_Value_union.connectionInfo.assocReqInfoElements.data); /*lint !e725 unifi_DataBlock : assocReqInfoElements*/
+ }
+ if (evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.length)
+ {
+ osa_free(evt.appValue.unifi_Value_union.connectionInfo.assocRspInfoElements.data); /*lint !e725 unifi_DataBlock : assocRspInfoElements*/
+ }
+ break;
+ case unifi_ConnectionStatsValue:
+ break;
+ case unifi_HostConfigValue:
+ break;
+ case unifi_MIBConfigValue:
+ break;
+ case unifi_PermanentMacAddressValue:
+ break;
+ case unifi_PowerConfigValue:
+ break;
+ case unifi_RoamingConfigValue:
+ break;
+ case unifi_SMEConfigValue:
+ break;
+ case unifi_ScanConfigValue:
+ if (evt.appValue.unifi_Value_union.scanControl.passiveChannelList.length)
+ {
+ osa_free(evt.appValue.unifi_Value_union.scanControl.passiveChannelList.data); /*lint !e725 unifi_DataBlock : passiveChannelList*/
+ }
+ break;
+ case unifi_StationMacAddressValue:
+ break;
+ case unifi_VersionsValue:
+ osa_free(evt.appValue.unifi_Value_union.versions.smeIdString); /* unifi_String : smeIdString */
+ break;
+ default:
+ break;
+ }
+ /* -----------------------------------------------------------------*/
+}
+
+static void event_to_unifi_mgt_mib_set_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtMibSetCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_mib_set_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_mib_get_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtMibGetCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ evt.mibAttributeValue.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : mibAttributeValue */
+ evt.mibAttributeValue.data = NULL;
+ if (evt.mibAttributeValue.length)
+ {
+ evt.mibAttributeValue.data = (uint8*)osa_malloc(evt.mibAttributeValue.length); /*lint !e725 unifi_DataBlock : mibAttributeValue*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.mibAttributeValue.data, evt.mibAttributeValue.length); /*lint !e545 !e725 unifi_DataBlock : mibAttributeValue */
+ }
+
+ unifi_mgt_mib_get_cfm(context, evt.status, &evt.mibAttributeValue);
+
+ if (evt.mibAttributeValue.length)
+ {
+ osa_free(evt.mibAttributeValue.data); /*lint !e725 unifi_DataBlock : mibAttributeValue*/
+ }
+}
+
+static void event_to_unifi_mgt_mib_get_next_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtMibGetNextCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ evt.mibAttribute.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : mibAttribute */
+ evt.mibAttribute.data = NULL;
+ if (evt.mibAttribute.length)
+ {
+ evt.mibAttribute.data = (uint8*)osa_malloc(evt.mibAttribute.length); /*lint !e725 unifi_DataBlock : mibAttribute*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.mibAttribute.data, evt.mibAttribute.length); /*lint !e545 !e725 unifi_DataBlock : mibAttribute */
+ }
+
+ unifi_mgt_mib_get_next_cfm(context, evt.status, &evt.mibAttribute);
+
+ if (evt.mibAttribute.length)
+ {
+ osa_free(evt.mibAttribute.data); /*lint !e725 unifi_DataBlock : mibAttribute*/
+ }
+}
+
+static void event_to_unifi_mgt_scan_full_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtScanFullCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_scan_full_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_scan_results_get_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtScanResultsGetCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.numElements = event_unpack_uint16(&buffer); /* uint16 : numElements */
+ evt.resultsBuffer.results = NULL;
+ if (evt.resultsBuffer.numElements)
+ {
+ int i;
+ evt.resultsBuffer.results = (unifi_ScanResult*)osa_malloc(sizeof(unifi_ScanResult) * evt.resultsBuffer.numElements);
+ for (i=0; i < evt.resultsBuffer.numElements; i++)
+ {
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.resultsBuffer.results[i].ssid.ssid, 32); /*lint !e545 !e725 uint8 : ssid */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].ssid.length = event_unpack_uint8(&buffer); /* uint8 : length */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.resultsBuffer.results[i].bssid.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].rssi = event_unpack_int16(&buffer); /* int16 : rssi */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].snr = event_unpack_int16(&buffer); /* int16 : snr */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].ifIndex = event_unpack_uint16(&buffer); /* unifi_RadioIF : ifIndex */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].beaconPeriod = event_unpack_uint16(&buffer); /* uint16 : beaconPeriod */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.resultsBuffer.results[i].timestamp.data, 8); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.resultsBuffer.results[i].localTime.data, 8); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].channelFrequency = event_unpack_uint16(&buffer); /* uint16 : channelFrequency */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].capabilityInformation = event_unpack_uint16(&buffer); /* uint16 : capabilityInformation */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].channelNumber = event_unpack_uint8(&buffer); /* uint8 : channelNumber */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].usability = event_unpack_uint16(&buffer); /* unifi_BasicUsability : usability */
+ /*lint -save -e545 -e725 */
+ evt.resultsBuffer.results[i].bssType = event_unpack_uint16(&buffer); /* unifi_BSSType : bssType */
+ evt.resultsBuffer.results[i].informationElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : informationElements */
+ evt.resultsBuffer.results[i].informationElements.data = NULL;
+ if (evt.resultsBuffer.results[i].informationElements.length)
+ {
+ evt.resultsBuffer.results[i].informationElements.data = (uint8*)osa_malloc(evt.resultsBuffer.results[i].informationElements.length); /*lint !e725 unifi_DataBlock : informationElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.resultsBuffer.results[i].informationElements.data, evt.resultsBuffer.results[i].informationElements.length); /*lint !e545 !e725 unifi_DataBlock : informationElements */
+ }
+ }
+ }
+
+ unifi_mgt_scan_results_get_cfm(context, evt.status, &evt.resultsBuffer);
+
+ if (evt.resultsBuffer.numElements)
+ {
+ int i;
+ for (i=0; i < evt.resultsBuffer.numElements; i++)
+ {
+ if (evt.resultsBuffer.results[i].informationElements.length)
+ {
+ osa_free(evt.resultsBuffer.results[i].informationElements.data); /*lint !e725 unifi_DataBlock : informationElements*/
+ }
+ }
+ osa_free(evt.resultsBuffer.results);
+ }
+}
+
+static void event_to_unifi_mgt_scan_result_ind(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtScanResultInd_Evt evt;
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.result.ssid.ssid, 32); /*lint !e545 !e725 uint8 : ssid */
+ /*lint -save -e545 -e725 */
+ evt.result.ssid.length = event_unpack_uint8(&buffer); /* uint8 : length */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.result.bssid.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.result.rssi = event_unpack_int16(&buffer); /* int16 : rssi */
+ /*lint -save -e545 -e725 */
+ evt.result.snr = event_unpack_int16(&buffer); /* int16 : snr */
+ /*lint -save -e545 -e725 */
+ evt.result.ifIndex = event_unpack_uint16(&buffer); /* unifi_RadioIF : ifIndex */
+ /*lint -save -e545 -e725 */
+ evt.result.beaconPeriod = event_unpack_uint16(&buffer); /* uint16 : beaconPeriod */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.result.timestamp.data, 8); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.result.localTime.data, 8); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.result.channelFrequency = event_unpack_uint16(&buffer); /* uint16 : channelFrequency */
+ /*lint -save -e545 -e725 */
+ evt.result.capabilityInformation = event_unpack_uint16(&buffer); /* uint16 : capabilityInformation */
+ /*lint -save -e545 -e725 */
+ evt.result.channelNumber = event_unpack_uint8(&buffer); /* uint8 : channelNumber */
+ /*lint -save -e545 -e725 */
+ evt.result.usability = event_unpack_uint16(&buffer); /* unifi_BasicUsability : usability */
+ /*lint -save -e545 -e725 */
+ evt.result.bssType = event_unpack_uint16(&buffer); /* unifi_BSSType : bssType */
+ evt.result.informationElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : informationElements */
+ evt.result.informationElements.data = NULL;
+ if (evt.result.informationElements.length)
+ {
+ evt.result.informationElements.data = (uint8*)osa_malloc(evt.result.informationElements.length); /*lint !e725 unifi_DataBlock : informationElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.result.informationElements.data, evt.result.informationElements.length); /*lint !e545 !e725 unifi_DataBlock : informationElements */
+ }
+
+ unifi_mgt_scan_result_ind(context, &evt.result);
+
+ if (evt.result.informationElements.length)
+ {
+ osa_free(evt.result.informationElements.data); /*lint !e725 unifi_DataBlock : informationElements*/
+ }
+}
+
+static void event_to_unifi_mgt_connect_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtConnectCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_connect_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_media_status_ind(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtMediaStatusInd_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.mediaStatus = event_unpack_uint16(&buffer); /* unifi_MediaStatus : mediaStatus */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.connectionInfo.ssid.ssid, 32); /*lint !e545 !e725 uint8 : ssid */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.ssid.length = event_unpack_uint8(&buffer); /* uint8 : length */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.connectionInfo.bssid.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.networkType80211 = event_unpack_uint16(&buffer); /* unifi_80211_NetworkType : networkType80211 */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.channelNumber = event_unpack_uint8(&buffer); /* uint8 : channelNumber */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.channelFrequency = event_unpack_uint16(&buffer); /* uint16 : channelFrequency */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.authMode = event_unpack_uint16(&buffer); /* unifi_AuthMode : authMode */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.ifIndex = event_unpack_uint16(&buffer); /* unifi_RadioIF : ifIndex */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.atimWindow = event_unpack_uint16(&buffer); /* uint16 : atimWindow */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.beaconPeriod = event_unpack_uint16(&buffer); /* uint16 : beaconPeriod */
+ evt.connectionInfo.assocScanInfoElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : assocScanInfoElements */
+ evt.connectionInfo.assocScanInfoElements.data = NULL;
+ if (evt.connectionInfo.assocScanInfoElements.length)
+ {
+ evt.connectionInfo.assocScanInfoElements.data = (uint8*)osa_malloc(evt.connectionInfo.assocScanInfoElements.length); /*lint !e725 unifi_DataBlock : assocScanInfoElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.connectionInfo.assocScanInfoElements.data, evt.connectionInfo.assocScanInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocScanInfoElements */
+ }
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.assocReqCapabilities = event_unpack_uint16(&buffer); /* uint16 : assocReqCapabilities */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.assocReqListenInterval = event_unpack_uint16(&buffer); /* uint16 : assocReqListenInterval */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.connectionInfo.assocReqApAddress.data, 6); /*lint !e545 !e725 uint8 : data */
+ evt.connectionInfo.assocReqInfoElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : assocReqInfoElements */
+ evt.connectionInfo.assocReqInfoElements.data = NULL;
+ if (evt.connectionInfo.assocReqInfoElements.length)
+ {
+ evt.connectionInfo.assocReqInfoElements.data = (uint8*)osa_malloc(evt.connectionInfo.assocReqInfoElements.length); /*lint !e725 unifi_DataBlock : assocReqInfoElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.connectionInfo.assocReqInfoElements.data, evt.connectionInfo.assocReqInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocReqInfoElements */
+ }
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.assocRspResult = event_unpack_uint16(&buffer); /* unifi_IEEE80211_Result : assocRspResult */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.assocRspCapabilityInfo = event_unpack_uint16(&buffer); /* uint16 : assocRspCapabilityInfo */
+ /*lint -save -e545 -e725 */
+ evt.connectionInfo.assocRspAssociationId = event_unpack_uint16(&buffer); /* uint16 : assocRspAssociationId */
+ evt.connectionInfo.assocRspInfoElements.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : assocRspInfoElements */
+ evt.connectionInfo.assocRspInfoElements.data = NULL;
+ if (evt.connectionInfo.assocRspInfoElements.length)
+ {
+ evt.connectionInfo.assocRspInfoElements.data = (uint8*)osa_malloc(evt.connectionInfo.assocRspInfoElements.length); /*lint !e725 unifi_DataBlock : assocRspInfoElements*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.connectionInfo.assocRspInfoElements.data, evt.connectionInfo.assocRspInfoElements.length); /*lint !e545 !e725 unifi_DataBlock : assocRspInfoElements */
+ }
+
+ unifi_mgt_media_status_ind(context, evt.mediaStatus, &evt.connectionInfo);
+
+ if (evt.connectionInfo.assocScanInfoElements.length)
+ {
+ osa_free(evt.connectionInfo.assocScanInfoElements.data); /*lint !e725 unifi_DataBlock : assocScanInfoElements*/
+ }
+ if (evt.connectionInfo.assocReqInfoElements.length)
+ {
+ osa_free(evt.connectionInfo.assocReqInfoElements.data); /*lint !e725 unifi_DataBlock : assocReqInfoElements*/
+ }
+ if (evt.connectionInfo.assocRspInfoElements.length)
+ {
+ osa_free(evt.connectionInfo.assocRspInfoElements.data); /*lint !e725 unifi_DataBlock : assocRspInfoElements*/
+ }
+}
+
+static void event_to_unifi_mgt_connection_quality_ind(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtConnectionQualityInd_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.unifiRSSI = event_unpack_int16(&buffer); /* int16 : unifiRSSI */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.unifiSNR = event_unpack_int16(&buffer); /* int16 : unifiSNR */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.unifiTxDataRate = event_unpack_uint8(&buffer); /* uint8 : unifiTxDataRate */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.unifiRxDataRate = event_unpack_uint8(&buffer); /* uint8 : unifiRxDataRate */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11RetryCount = event_unpack_uint32(&buffer); /* uint32 : dot11RetryCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11MultipleRetryCount = event_unpack_uint32(&buffer); /* uint32 : dot11MultipleRetryCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11ACKFailureCount = event_unpack_uint32(&buffer); /* uint32 : dot11ACKFailureCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11FrameDuplicateCount = event_unpack_uint32(&buffer); /* uint32 : dot11FrameDuplicateCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11FCSErrorCount = event_unpack_uint32(&buffer); /* uint32 : dot11FCSErrorCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11RTSSuccessCount = event_unpack_uint32(&buffer); /* uint32 : dot11RTSSuccessCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11RTSFailureCount = event_unpack_uint32(&buffer); /* uint32 : dot11RTSFailureCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11ReceivedFragmentCount = event_unpack_uint32(&buffer); /* uint32 : dot11ReceivedFragmentCount */
+ /*lint -save -e545 -e725 */
+ evt.connectionStats.dot11TransmittedFragmentCount = event_unpack_uint32(&buffer); /* uint32 : dot11TransmittedFragmentCount */
+
+ unifi_mgt_connection_quality_ind(context, &evt.connectionStats);
+
+}
+
+static void event_to_unifi_mgt_disconnect_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtDisconnectCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_disconnect_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_multicast_address_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtMulticastAddressCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.action = event_unpack_uint16(&buffer); /* unifi_ListAction : action */
+ /*lint -save -e545 -e725 */
+ evt.getAddresses.numElements = event_unpack_uint8(&buffer); /* uint8 : numElements */
+ evt.getAddresses.addresses = NULL;
+ if (evt.getAddresses.numElements)
+ {
+ int i;
+ evt.getAddresses.addresses = (unifi_MACAddress*)osa_malloc(sizeof(unifi_MACAddress) * evt.getAddresses.numElements);
+ for (i=0; i < evt.getAddresses.numElements; i++)
+ {
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.getAddresses.addresses[i].data, 6); /*lint !e545 !e725 uint8 : data */
+ }
+ }
+
+ unifi_mgt_multicast_address_cfm(context, evt.status, evt.action, &evt.getAddresses);
+
+ if (evt.getAddresses.numElements)
+ {
+ int i;
+ for (i=0; i < evt.getAddresses.numElements; i++)
+ {
+ }
+ osa_free(evt.getAddresses.addresses);
+ }
+}
+
+static void event_to_unifi_mgt_mic_failure_ind(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtMicFailureInd_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.secondFailure = event_unpack_int16(&buffer); /* Boolean : secondFailure */
+ /*lint -save -e545 -e725 */
+ evt.count = event_unpack_uint16(&buffer); /* uint16 : count */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.address.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.keyType = event_unpack_uint16(&buffer); /* unifi_KeyType : keyType */
+ /*lint -save -e545 -e725 */
+ evt.keyId = event_unpack_uint16(&buffer); /* uint16 : keyId */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.tSC.data, 8); /*lint !e545 !e725 uint8 : data */
+
+ unifi_mgt_mic_failure_ind(context, evt.secondFailure, evt.count, &evt.address, evt.keyType, evt.keyId, &evt.tSC);
+
+}
+
+static void event_to_unifi_mgt_pmkid_candidate_list_ind(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtPmkidCandidateListInd_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.candidates.numElements = event_unpack_uint8(&buffer); /* uint8 : numElements */
+ evt.candidates.pmkidCandidates = NULL;
+ if (evt.candidates.numElements)
+ {
+ int i;
+ evt.candidates.pmkidCandidates = (unifi_PmkidCandidate*)osa_malloc(sizeof(unifi_PmkidCandidate) * evt.candidates.numElements);
+ for (i=0; i < evt.candidates.numElements; i++)
+ {
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.candidates.pmkidCandidates[i].bssid.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ evt.candidates.pmkidCandidates[i].preAuthAllowed = event_unpack_int16(&buffer); /* Boolean : preAuthAllowed */
+ }
+ }
+
+ unifi_mgt_pmkid_candidate_list_ind(context, &evt.candidates);
+
+ if (evt.candidates.numElements)
+ {
+ int i;
+ for (i=0; i < evt.candidates.numElements; i++)
+ {
+ }
+ osa_free(evt.candidates.pmkidCandidates);
+ }
+}
+
+static void event_to_unifi_mgt_pmkid_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtPmkidCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.action = event_unpack_uint16(&buffer); /* unifi_ListAction : action */
+ /*lint -save -e545 -e725 */
+ evt.getPmkidList.numElements = event_unpack_uint8(&buffer); /* uint8 : numElements */
+ evt.getPmkidList.pmkids = NULL;
+ if (evt.getPmkidList.numElements)
+ {
+ int i;
+ evt.getPmkidList.pmkids = (unifi_Pmkid*)osa_malloc(sizeof(unifi_Pmkid) * evt.getPmkidList.numElements);
+ for (i=0; i < evt.getPmkidList.numElements; i++)
+ {
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.getPmkidList.pmkids[i].bssid.data, 6); /*lint !e545 !e725 uint8 : data */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.getPmkidList.pmkids[i].pmkid, 16); /*lint !e545 !e725 uint8 : pmkid */
+ }
+ }
+
+ unifi_mgt_pmkid_cfm(context, evt.status, evt.action, &evt.getPmkidList);
+
+ if (evt.getPmkidList.numElements)
+ {
+ int i;
+ for (i=0; i < evt.getPmkidList.numElements; i++)
+ {
+ }
+ osa_free(evt.getPmkidList.pmkids);
+ }
+}
+
+static void event_to_unifi_mgt_key_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtKeyCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.action = event_unpack_uint16(&buffer); /* unifi_ListAction : action */
+
+ unifi_mgt_key_cfm(context, evt.status, evt.action);
+
+}
+
+static void event_to_unifi_mgt_packet_filter_set_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtPacketFilterSetCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_mgt_packet_filter_set_cfm(context, evt.status);
+
+}
+
+static void event_to_unifi_mgt_tspec_cfm(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtTspecCfm_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.transactionId = event_unpack_uint32(&buffer); /* uint32 : transactionId */
+ /*lint -save -e545 -e725 */
+ evt.tspecResultCode = event_unpack_uint16(&buffer); /* unifi_TspecResultCode : tspecResultCode */
+ evt.tspec.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : tspec */
+ evt.tspec.data = NULL;
+ if (evt.tspec.length)
+ {
+ evt.tspec.data = (uint8*)osa_malloc(evt.tspec.length); /*lint !e725 unifi_DataBlock : tspec*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.tspec.data, evt.tspec.length); /*lint !e545 !e725 unifi_DataBlock : tspec */
+ }
+
+ unifi_mgt_tspec_cfm(context, evt.status, evt.transactionId, evt.tspecResultCode, &evt.tspec);
+
+ if (evt.tspec.length)
+ {
+ osa_free(evt.tspec.data); /*lint !e725 unifi_DataBlock : tspec*/
+ }
+}
+
+static void event_to_unifi_mgt_tspec_ind(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiMgtTspecInd_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.action = event_unpack_uint16(&buffer); /* unifi_ListAction : action */
+ /*lint -save -e545 -e725 */
+ evt.transactionId = event_unpack_uint32(&buffer); /* uint32 : transactionId */
+
+ unifi_mgt_tspec_ind(context, evt.action, evt.transactionId);
+
+}
+
+typedef void (*event_to_fn)(FsmContext* context, uint8* inputbuffer, uint16 size);
+static const event_to_fn fnlookup[41] = {
+ NULL,
+ event_to_unifi_mgt_wifi_on_cfm,
+ NULL,
+ event_to_unifi_mgt_wifi_off_cfm,
+ event_to_unifi_mgt_wifi_off_ind,
+ NULL,
+ event_to_unifi_mgt_wifi_flightmode_cfm,
+ NULL,
+ event_to_unifi_mgt_set_value_cfm,
+ NULL,
+ event_to_unifi_mgt_get_value_cfm,
+ NULL,
+ event_to_unifi_mgt_mib_set_cfm,
+ NULL,
+ event_to_unifi_mgt_mib_get_cfm,
+ NULL,
+ event_to_unifi_mgt_mib_get_next_cfm,
+ NULL,
+ event_to_unifi_mgt_scan_full_cfm,
+ NULL,
+ event_to_unifi_mgt_scan_results_get_cfm,
+ event_to_unifi_mgt_scan_result_ind,
+ NULL,
+ event_to_unifi_mgt_connect_cfm,
+ event_to_unifi_mgt_media_status_ind,
+ event_to_unifi_mgt_connection_quality_ind,
+ NULL,
+ event_to_unifi_mgt_disconnect_cfm,
+ NULL,
+ event_to_unifi_mgt_multicast_address_cfm,
+ event_to_unifi_mgt_mic_failure_ind,
+ event_to_unifi_mgt_pmkid_candidate_list_ind,
+ NULL,
+ event_to_unifi_mgt_pmkid_cfm,
+ NULL,
+ event_to_unifi_mgt_key_cfm,
+ NULL,
+ event_to_unifi_mgt_packet_filter_set_cfm,
+ NULL,
+ event_to_unifi_mgt_tspec_cfm,
+ event_to_unifi_mgt_tspec_ind,
+};
+
+Boolean remote_mgt_signal_receive(FsmContext* context, uint8* buffer, uint16 size)
+{
+ uint8* tempbuffer = buffer;
+ uint16 id = event_unpack_uint16(&tempbuffer);
+ uint16 idx = id - 0x9001;
+
+ if (idx < 41)
+ {
+ if (fnlookup[idx])
+ {
+ (*fnlookup[idx])(context, buffer, size);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_mgt_sap.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_mgt_sap.c
new file mode 100644
index 0000000..241e8fb
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_mgt_sap.c
@@ -0,0 +1,269 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: sme_mgt_sap.c
+ *
+ * PURPOSE:
+ * This file provides the SME MGT API implementation.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#include "unifi_priv.h"
+#include "sme_top_level_fsm/sme.h"
+#include "mgt_sap/mgt_sap_build_functions.h"
+
+
+void unifi_mgt_wifi_on_req(FsmContext* context, const unifi_MACAddress* address, const unifi_DataBlockList* mibFiles)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_wifi_on_req()\n");
+
+ buflen = build_packed_unifi_mgt_wifi_on_req(&buf, address, mibFiles);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_wifi_off_req(FsmContext* context)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_wifi_off_req\n");
+
+ buflen = build_packed_unifi_mgt_wifi_off_req(&buf);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_set_value_req(FsmContext* context,
+ const unifi_AppValue* appValue)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_set_value_req(%d)\n", appValue->id);
+
+ buflen = build_packed_unifi_mgt_set_value_req(&buf, appValue);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_get_value_req(FsmContext* context, unifi_AppValueId appValueId)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_get_value_req(%d)\n", appValueId);
+
+ buflen = build_packed_unifi_mgt_get_value_req(&buf, appValueId);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_mib_get_req(FsmContext* context,
+ const unifi_DataBlock* mibAttribute)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_mib_get_req\n");
+
+ buflen = build_packed_unifi_mgt_mib_get_req(&buf, mibAttribute);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_mib_set_req(FsmContext* context,
+ const unifi_DataBlock* mibAttribute)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_mib_set_req\n");
+
+ buflen = build_packed_unifi_mgt_mib_set_req(&buf, mibAttribute);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_mib_get_next_req(FsmContext* context,
+ const unifi_DataBlock* mibAttribute)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_mib_get_next_req\n");
+
+ buflen = build_packed_unifi_mgt_mib_get_next_req(&buf, mibAttribute);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_scan_full_req(FsmContext* context,
+ const unifi_SSID* ssid,
+ Boolean forceScan,
+ unifi_ScanType scanType,
+ const unifi_DataBlock* channelList)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_scan_full_req\n");
+
+ buflen = build_packed_unifi_mgt_scan_full_req(&buf, ssid, forceScan, scanType, channelList);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_scan_results_get_req(FsmContext* context)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_scan_results_get_req\n");
+
+ buflen = build_packed_unifi_mgt_scan_results_get_req(&buf);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_connect_req(FsmContext* context,
+ const unifi_ConnectionConfig* connectionConfig)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_connect_req\n");
+
+ buflen = build_packed_unifi_mgt_connect_req(&buf, connectionConfig);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_disconnect_req(FsmContext* context)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_disconnect_req\n");
+
+ buflen = build_packed_unifi_mgt_disconnect_req(&buf);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_multicast_address_req(FsmContext* context,
+ unifi_ListAction action,
+ const unifi_MulticastAddressList* addresses)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_multicast_address_req\n");
+
+ buflen = build_packed_unifi_mgt_multicast_address_req(&buf, action,
+ addresses);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_pmkid_req(FsmContext* context, unifi_ListAction action,
+ const unifi_PmkidList* pmkids)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_pmkid_req\n");
+
+ buflen = build_packed_unifi_mgt_pmkid_req(&buf, action, pmkids);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_key_req(FsmContext* context, unifi_ListAction action,
+ const unifi_Key* key)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_key_req\n");
+
+ buflen = build_packed_unifi_mgt_key_req(&buf, action, key);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_packet_filter_set_req(FsmContext* context,
+ const unifi_DataBlock* filter,
+ unifi_PacketFilterMode mode,
+ unifi_IPV4Address ipV4Address)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_packet_filter_set_req\n");
+
+ buflen = build_packed_unifi_mgt_packet_filter_set_req(&buf, filter,
+ mode, ipV4Address);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_mgt_tspec_req(FsmContext* context,
+ unifi_ListAction action,
+ uint32 transactionId,
+ Boolean strict,
+ const unifi_DataBlock* tspec,
+ const unifi_DataBlock* tclas)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_mgt_tspec_req\n");
+
+ buflen = build_packed_unifi_mgt_tspec_req(&buf, action, transactionId,
+ strict, tspec, tclas);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_proxy.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_proxy.c
new file mode 100644
index 0000000..4872231
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_proxy.c
@@ -0,0 +1,49 @@
+/** @file sme_proxy.c
+ *
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2006-2007. All rights reserved.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ ****************************************************************************/
+
+#include "unifi_priv.h"
+#include "event_pack_unpack/event_pack_unpack.h"
+
+/*
+ * If message in buffer is a HIP signal, pass to HIP layer for sending
+ * to UniFi. Return 1 to say we handled the message.
+ * Otherwise return 0 to say we didn't handle the message.
+ */
+int
+receive_remote_sys_hip_req(FsmContext* context, uint8 *buffer, uint32 length)
+{
+ uint8* tempbuffer = buffer;
+ uint16 id = event_unpack_uint16(&tempbuffer);
+
+ if (id >= 0x0100 && id < 0x1000) {
+ unifi_DataBlock mlmeCommand;
+ unifi_DataBlock dataref1;
+ unifi_DataBlock dataref2;
+
+ mlmeCommand.length = (uint16)length;
+ mlmeCommand.data = buffer;
+
+ tempbuffer += 6; /* Skip the 4 bytes for dest, sender and 1st slotnumber */
+ dataref1.length = event_unpack_uint16(&tempbuffer);
+ tempbuffer += 2; /* Skip the slot number */
+ dataref2.length = event_unpack_uint16(&tempbuffer);
+
+ dataref1.data = buffer + ((length - dataref2.length) - dataref1.length);
+ dataref2.data = buffer + length - dataref2.length;
+
+ mlmeCommand.length -= dataref1.length + dataref2.length;
+
+ unifi_sys_hip_req(context, &mlmeCommand, &dataref1, &dataref2);
+
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_sys_sap.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_sys_sap.c
new file mode 100644
index 0000000..3fafa80
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_sys_sap.c
@@ -0,0 +1,262 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: sme_sys_sap.c
+ *
+ * PURPOSE:
+ * This file provides the SME SYS API implementation.
+ *
+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#include "unifi_priv.h"
+#include "sme_top_level_fsm/sme.h"
+#include "sys_sap/sys_sap_build_functions.h"
+
+
+void unifi_sys_wifi_on_ind(FsmContext* context, unifi_Status status,
+ const unifi_Versions* versions)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_wifi_on_ind(%d)\n", status);
+
+ buflen = build_packed_unifi_sys_wifi_on_ind(&buf, status, versions);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_wifi_on_cfm(FsmContext* context, unifi_Status status)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_wifi_on_cfm(%d)\n", status);
+
+ buflen = build_packed_unifi_sys_wifi_on_cfm(&buf, status);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_wifi_off_ind(FsmContext* context,
+ unifi_ControlIndication controlIndication)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_wifi_off_ind\n");
+
+ buflen = build_packed_unifi_sys_wifi_off_ind(&buf, controlIndication);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_wifi_off_cfm(FsmContext* context)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_wifi_off_cfm\n");
+
+ buflen = build_packed_unifi_sys_wifi_off_cfm(&buf);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_suspend_ind(FsmContext* context, Boolean hardSuspend, Boolean d3Suspend)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_suspend_ind(%d, %d)\n", hardSuspend, d3Suspend);
+
+ buflen = build_packed_unifi_sys_suspend_ind(&buf, hardSuspend, d3Suspend);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_resume_ind(FsmContext* context, Boolean resumePowerMaintained)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2,
+ "unifi_sys_resume_ind(%d)\n", resumePowerMaintained);
+
+ buflen = build_packed_unifi_sys_resume_ind(&buf, resumePowerMaintained);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_hip_ind(FsmContext* context, const unifi_DataBlock* mlmeCommand,
+ const unifi_DataBlock* dataRef1,
+ const unifi_DataBlock* dataRef2)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_hip_ind\n");
+
+ buflen = build_packed_unifi_sys_hip_ind(&buf, mlmeCommand,
+ dataRef1, dataRef2);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_qos_control_cfm(FsmContext* context, unifi_Status status)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_qos_control_cfm(%d)\n", status);
+
+ buflen = build_packed_unifi_sys_qos_control_cfm(&buf, status);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_port_configure_cfm(FsmContext* context, unifi_Status status,
+ const unifi_MACAddress* macAddress)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_port_configure_cfm(%d)\n", status);
+
+ buflen = build_packed_unifi_sys_port_configure_cfm(&buf, status,
+ macAddress);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_sys_traffic_protocol_ind(FsmContext* context,
+ unifi_traffic_packettype packetType,
+ unifi_protocol_direction direction,
+ const unifi_MACAddress* srcAddress)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_traffic_protocol_ind\n");
+
+ buflen = build_packed_unifi_sys_traffic_protocol_ind(&buf,
+ packetType,
+ direction,
+ srcAddress);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+void unifi_sys_traffic_sample_ind(FsmContext* context, const unifi_traffic_stats* stats)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_traffic_protocol_ind\n");
+
+ buflen = build_packed_unifi_sys_traffic_sample_ind(&buf,stats);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_ip_configured_ind(FsmContext* context, Boolean ipConfigured)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2,
+ "unifi_sys_ip_configured_ind(%d)\n", ipConfigured);
+
+ buflen = build_packed_unifi_sys_ip_configured_ind(&buf, ipConfigured);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_multicast_address_ind(FsmContext* context,
+ unifi_ListAction action,
+ const unifi_MulticastAddressList* addresses)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_multicast_address_ind\n");
+
+ buflen = build_packed_unifi_sys_multicast_address_ind(&buf,
+ action,
+ addresses);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_tclas_add_cfm(FsmContext* context, unifi_Status status)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_tclas_add_cfm(%d)\n", status);
+
+ buflen = build_packed_unifi_sys_tclas_add_cfm(&buf, status);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
+
+void unifi_sys_tclas_del_cfm(FsmContext* context, unifi_Status status)
+{
+ unifi_priv_t* priv = (unifi_priv_t*)context;
+ uint8* buf;
+ uint16 buflen;
+
+ unifi_trace(priv, UDBG2, "unifi_sys_tclas_del_cfm(%d)\n", status);
+
+ buflen = build_packed_unifi_sys_tclas_del_cfm(&buf, status);
+
+ /* Send message to user space */
+ sme_queue_message(priv, buf, buflen);
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.c
new file mode 100644
index 0000000..4ae09af
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.c
@@ -0,0 +1,213 @@
+/*
+ *****************************************************************************
+ *
+ * FILE : sme_userspace.c
+ *
+ * PURPOSE : Support functions for userspace SME helper application.
+ *
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ *****************************************************************************
+ */
+
+#include "unifi_priv.h"
+
+
+
+int
+uf_sme_init(unifi_priv_t *priv)
+{
+ priv->smepriv = priv;
+
+ init_waitqueue_head(&priv->sme_request_wq);
+
+#ifdef CSR_SUPPORT_WEXT
+ priv->ignore_bssid_join = FALSE;
+ priv->mib_data.length = 0;
+
+ priv->filter_tclas_ies = NULL;
+ memset(&priv->packet_filters, 0, sizeof(uf_cfg_bcast_packet_filter_t));
+
+ uf_sme_wext_set_defaults(priv);
+#endif /* CSR_SUPPORT_WEXT*/
+
+ priv->sta_ip_address = 0xFFFFFFFF;
+
+ memset(&priv->controlled_port_cfg, 0, sizeof(controlled_port_config));
+
+ priv->wifi_on_state = wifi_on_unspecified;
+
+ sema_init(&priv->sme_sem, 1);
+ memset(&priv->sme_reply, 0, sizeof(sme_reply_t));
+
+ /* Create a work queue item for Traffic Analysis indications to SME */
+ INIT_WORK(&priv->ta_ind_work.task, uf_ta_ind_wq);
+ INIT_WORK(&priv->ta_sample_ind_work.task, uf_ta_sample_ind_wq);
+#ifdef CSR_SUPPORT_WEXT
+ INIT_WORK(&priv->sme_config_task, uf_sme_config_wq);
+#endif
+
+ return 0;
+} /* uf_sme_init() */
+
+
+void
+uf_sme_deinit(unifi_priv_t *priv)
+{
+#ifdef CSR_SUPPORT_WEXT
+ /* Free any TCLASs previously allocated */
+ if (priv->packet_filters.tclas_ies_length) {
+ unifi_free(priv, priv->filter_tclas_ies);
+ priv->filter_tclas_ies = NULL;
+ }
+#endif /* CSR_SUPPORT_WEXT*/
+
+ priv->smepriv = NULL;
+
+} /* uf_sme_deinit() */
+
+
+
+
+int
+sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length)
+{
+ ul_client_t *pcli;
+ udi_log_t *logptr;
+ udi_msg_t *msgptr;
+ u8 *p;
+
+ func_enter();
+
+ /* Just a sanity check */
+ if ((buffer == NULL) || (length <= 0)) {
+ return -EINVAL;
+ }
+
+ pcli = priv->sme_cli;
+ if (pcli == NULL) {
+ osa_free(buffer);
+ return -EINVAL;
+ }
+
+ /* Allocate log structure plus actual signal. */
+ logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + length, GFP_KERNEL);
+ if (logptr == NULL) {
+ unifi_error(priv, "Failed to allocate %d bytes for an SME message\n",
+ sizeof(udi_log_t) + length);
+ osa_free(buffer);
+ return -ENOMEM;
+ }
+
+ /* Fill in udi_log struct */
+ INIT_LIST_HEAD(&logptr->q);
+ msgptr = &logptr->msg;
+ msgptr->length = sizeof(udi_msg_t) + length;
+ msgptr->signal_length = length;
+
+ /* Copy signal and bulk data to the log */
+ p = (u8 *)(msgptr + 1);
+ memcpy(p, buffer, length);
+
+ /* Add to tail of log queue */
+ down(&pcli->udi_sem);
+ list_add_tail(&logptr->q, &pcli->udi_log);
+ up(&pcli->udi_sem);
+
+ /* Wake any waiting user process */
+ wake_up_interruptible(&pcli->udi_wq);
+
+ /* It is our responsibility to free the buffer allocated in build_packed_*() */
+ osa_free(buffer);
+
+ func_exit();
+
+ return 0;
+
+} /* sme_queue_message() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_ta_indicate_protocol
+ *
+ * Report that a packet of a particular type has been seen
+ *
+ * Arguments:
+ * drv_priv The device context pointer passed to ta_init.
+ * protocol The protocol type enum value.
+ * direction Whether the packet was a tx or rx.
+ * src_addr The source MAC address from the data packet.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * We defer the actual sending to a background workqueue,
+ * see uf_ta_ind_wq().
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_ta_indicate_protocol(void *ospriv,
+ unifi_traffic_packettype packet_type,
+ unifi_protocol_direction direction,
+ const unifi_MACAddress *src_addr)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+
+ if (priv->ta_ind_work.in_use) {
+ unifi_warning(priv,
+ "unifi_ta_indicate_protocol: workqueue item still in use, not sending\n");
+ return;
+ }
+
+ priv->ta_ind_work.packet_type = packet_type;
+ priv->ta_ind_work.direction = direction;
+ priv->ta_ind_work.src_addr = *src_addr;
+
+ queue_work(priv->unifi_workqueue, &priv->ta_ind_work.task);
+
+} /* unifi_ta_indicate_protocol() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_ta_indicate_sampling
+ *
+ * Send the TA sampling information to the SME.
+ *
+ * Arguments:
+ * drv_priv The device context pointer passed to ta_init.
+ * stats The TA sampling data to send.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_ta_indicate_sampling(void *ospriv, unifi_traffic_stats *stats)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+
+ if (!priv) {
+ return;
+ }
+
+ if (priv->ta_sample_ind_work.in_use) {
+ unifi_warning(priv,
+ "unifi_ta_indicate_sampling: workqueue item still in use, not sending\n");
+ return;
+ }
+
+ priv->ta_sample_ind_work.stats = *stats;
+
+ queue_work(priv->unifi_workqueue, &priv->ta_sample_ind_work.task);
+
+} /* unifi_ta_indicate_sampling() */
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.h
new file mode 100644
index 0000000..6deb1f7
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sme_userspace.h
@@ -0,0 +1,31 @@
+/*
+ * ***************************************************************************
+ * FILE: sme_userspace.h
+ *
+ * PURPOSE: SME related definitions.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#ifndef __LINUX_SME_USERSPACE_H__
+#define __LINUX_SME_USERSPACE_H__ 1
+
+#include <linux/kernel.h>
+
+#include "sme_top_level_fsm/sme.h"
+#include "sys_sap/sys_sap_remote_sme_interface.h"
+#include "mgt_sap/mgt_sap_remote_sme_interface.h"
+
+int uf_sme_init(unifi_priv_t *priv);
+void uf_sme_deinit(unifi_priv_t *priv);
+
+int sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length);
+
+int receive_remote_sys_hip_req(FsmContext* context, uint8 *buffer, uint32 length);
+
+
+#endif /* __LINUX_SME_USERSPACE_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.c
new file mode 100644
index 0000000..03051ab
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.c
@@ -0,0 +1,344 @@
+/* This is an autogenerated file from sme__build_signal_c.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#include "fsm/fsm.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "smeio/smeio_fsm_events.h"
+#include "event_pack_unpack/event_pack_unpack.h"
+
+uint16 build_packed_unifi_sys_wifi_on_ind(uint8** resultBuffer, unifi_Status status, const unifi_Versions* versions)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; status */
+ /* packedSize += 4; versions->chipId */
+ /* packedSize += 4; versions->chipVersion */
+ /* packedSize += 4; versions->firmwareBuild */
+ /* packedSize += 4; versions->firmwareHip */
+ /* packedSize += 4; versions->driverBuild */
+ /* packedSize += 4; versions->driverHip */
+ /* packedSize += 4; versions->driverApi */
+ /* packedSize += 4; versions->smeBuild */
+ /* packedSize += 4; versions->smeVariant */
+ /* packedSize += 4; versions->smeDriverApi */
+ /* packedSize += 4; versions->smeHip */
+ /* packedSize += 4; versions->smeSapApi */
+ packedSize += (uint16)osa_strlen(versions->smeIdString) + 3; /* unifi_String :: smeIdString */
+ packedSize += 50; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_WIFI_ON_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)status); /* status */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->chipId); /* chipId */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->chipVersion); /* chipVersion */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->firmwareBuild); /* firmwareBuild */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->firmwareHip); /* firmwareHip */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->driverBuild); /* driverBuild */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->driverHip); /* driverHip */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->driverApi); /* driverApi */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->smeBuild); /* smeBuild */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->smeVariant); /* smeVariant */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->smeDriverApi); /* smeDriverApi */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->smeHip); /* smeHip */
+ packedLength += event_pack_uint32(&buffer, (uint32)versions->smeSapApi); /* smeSapApi */
+ packedLength += event_pack_string(&buffer, versions->smeIdString); /* unifi_String : smeIdString */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_wifi_on_cfm(uint8** resultBuffer, unifi_Status status)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; status */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_WIFI_ON_CFM_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)status); /* status */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_wifi_off_ind(uint8** resultBuffer, unifi_ControlIndication controlIndication)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; controlIndication */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_WIFI_OFF_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)controlIndication); /* controlIndication */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_wifi_off_cfm(uint8** resultBuffer)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_WIFI_OFF_CFM_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_suspend_ind(uint8** resultBuffer, Boolean hardSuspend, Boolean d3Suspend)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; hardSuspend */
+ /* packedSize += 2; d3Suspend */
+ packedSize += 4; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_SUSPEND_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_int16(&buffer, (int16)hardSuspend); /* hardSuspend */
+ packedLength += event_pack_int16(&buffer, (int16)d3Suspend); /* d3Suspend */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_resume_ind(uint8** resultBuffer, Boolean resumePowerMaintained)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; resumePowerMaintained */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_RESUME_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_int16(&buffer, (int16)resumePowerMaintained); /* resumePowerMaintained */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_hip_ind(uint8** resultBuffer, const unifi_DataBlock* mlmeCommand, const unifi_DataBlock* dataRef1, const unifi_DataBlock* dataRef2)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ packedSize += mlmeCommand->length + 2; /*lint !e725*/ /* unifi_DataBlock :: mlmeCommand */
+ packedSize += dataRef1->length + 2; /*lint !e725*/ /* unifi_DataBlock :: dataRef1 */
+ packedSize += dataRef2->length + 2; /*lint !e725*/ /* unifi_DataBlock :: dataRef2 */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_HIP_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, mlmeCommand->length); /*lint !e725 unifi_DataBlock : mlmeCommand */
+ packedLength += event_pack_buffer(&buffer, mlmeCommand->data, mlmeCommand->length); /*lint !e545 !e725 unifi_DataBlock : mlmeCommand */
+ packedLength += event_pack_uint16(&buffer, dataRef1->length); /*lint !e725 unifi_DataBlock : dataRef1 */
+ packedLength += event_pack_buffer(&buffer, dataRef1->data, dataRef1->length); /*lint !e545 !e725 unifi_DataBlock : dataRef1 */
+ packedLength += event_pack_uint16(&buffer, dataRef2->length); /*lint !e725 unifi_DataBlock : dataRef2 */
+ packedLength += event_pack_buffer(&buffer, dataRef2->data, dataRef2->length); /*lint !e545 !e725 unifi_DataBlock : dataRef2 */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_qos_control_cfm(uint8** resultBuffer, unifi_Status status)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; status */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_QOS_CONTROL_CFM_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)status); /* status */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_port_configure_cfm(uint8** resultBuffer, unifi_Status status, const unifi_MACAddress* macAddress)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; status */
+ /* packedSize += 6; macAddress->data */
+ packedSize += 8; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_PORT_CONFIGURE_CFM_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)status); /* status */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&macAddress->data, 6); /*lint !e545 !e725 data */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_traffic_sample_ind(uint8** resultBuffer, const unifi_traffic_stats* stats)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 4; stats->rxFramesNum */
+ /* packedSize += 4; stats->txFramesNum */
+ /* packedSize += 4; stats->rxBytesCount */
+ /* packedSize += 4; stats->txBytesCount */
+ /* packedSize += 11; stats->intervals */
+ packedSize += 27; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_TRAFFIC_SAMPLE_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint32(&buffer, (uint32)stats->rxFramesNum); /* rxFramesNum */
+ packedLength += event_pack_uint32(&buffer, (uint32)stats->txFramesNum); /* txFramesNum */
+ packedLength += event_pack_uint32(&buffer, (uint32)stats->rxBytesCount); /* rxBytesCount */
+ packedLength += event_pack_uint32(&buffer, (uint32)stats->txBytesCount); /* txBytesCount */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&stats->intervals, 11); /*lint !e545 !e725 intervals */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_traffic_protocol_ind(uint8** resultBuffer, unifi_traffic_packettype packetType, unifi_protocol_direction direction, const unifi_MACAddress* srcAddress)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; packetType */
+ /* packedSize += 2; direction */
+ /* packedSize += 6; srcAddress->data */
+ packedSize += 10; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_TRAFFIC_PROTOCOL_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)packetType); /* packetType */
+ packedLength += event_pack_uint16(&buffer, (uint16)direction); /* direction */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&srcAddress->data, 6); /*lint !e545 !e725 data */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_ip_configured_ind(uint8** resultBuffer, Boolean ipConfigured)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; ipConfigured */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_IP_CONFIGURED_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_int16(&buffer, (int16)ipConfigured); /* ipConfigured */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_multicast_address_ind(uint8** resultBuffer, unifi_ListAction action, const unifi_MulticastAddressList* setAddresses)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; action */
+ /* packedSize += 1; setAddresses->numElements */
+ {
+ int i;
+ for (i = 0; i < setAddresses->numElements; i++)
+ {
+ /* packedSize += 6; setAddresses->addresses[i].data */
+ packedSize += 6;
+ }
+ }
+ packedSize += 3; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_MULTICAST_ADDRESS_IND_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)action); /* action */
+ packedLength += event_pack_buffer(&buffer, (uint8*)&setAddresses->numElements, 1); /*lint !e545 !e725 numElements */
+ {
+ int i;
+ for (i = 0; i < setAddresses->numElements; i++)
+ {
+ packedLength += event_pack_buffer(&buffer, (uint8*)&setAddresses->addresses[i].data, 6); /*lint !e545 !e725 data */
+ }
+ }
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_tclas_add_cfm(uint8** resultBuffer, unifi_Status status)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; status */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_TCLAS_ADD_CFM_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)status); /* status */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
+uint16 build_packed_unifi_sys_tclas_del_cfm(uint8** resultBuffer, unifi_Status status)
+{
+ uint16 packedLength = 0;
+ uint16 packedSize = 6;
+ uint8* evt;
+ uint8* buffer;
+ /* packedSize += 2; status */
+ packedSize += 2; /* Size of Fixed elements */
+ evt = (uint8*)osa_malloc(packedSize);
+ buffer = evt;
+ packedLength += event_pack_uint16(&buffer, UNIFI_SYS_TCLAS_DEL_CFM_ID);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, 0);
+ packedLength += event_pack_uint16(&buffer, (uint16)status); /* status */
+ *resultBuffer = evt;
+ return packedLength;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.h
new file mode 100644
index 0000000..abac526
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_build_functions.h
@@ -0,0 +1,40 @@
+/* This is an autogenerated file from sme__build_signal_h.pl */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __SYS_BUILD_FUNCTIONS_H__
+#define __SYS_BUILD_FUNCTIONS_H__
+
+#include "fsm/fsm.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "smeio/smeio_fsm_events.h"
+
+extern uint16 build_packed_unifi_sys_wifi_on_ind(uint8** resultBuffer, unifi_Status status, const unifi_Versions* versions);
+extern uint16 build_packed_unifi_sys_wifi_on_cfm(uint8** resultBuffer, unifi_Status status);
+extern uint16 build_packed_unifi_sys_wifi_off_ind(uint8** resultBuffer, unifi_ControlIndication controlIndication);
+extern uint16 build_packed_unifi_sys_wifi_off_cfm(uint8** resultBuffer);
+extern uint16 build_packed_unifi_sys_suspend_ind(uint8** resultBuffer, Boolean hardSuspend, Boolean d3Suspend);
+extern uint16 build_packed_unifi_sys_resume_ind(uint8** resultBuffer, Boolean resumePowerMaintained);
+extern uint16 build_packed_unifi_sys_hip_ind(uint8** resultBuffer, const unifi_DataBlock* mlmeCommand, const unifi_DataBlock* dataRef1, const unifi_DataBlock* dataRef2);
+extern uint16 build_packed_unifi_sys_qos_control_cfm(uint8** resultBuffer, unifi_Status status);
+extern uint16 build_packed_unifi_sys_port_configure_cfm(uint8** resultBuffer, unifi_Status status, const unifi_MACAddress* macAddress);
+extern uint16 build_packed_unifi_sys_traffic_sample_ind(uint8** resultBuffer, const unifi_traffic_stats* stats);
+extern uint16 build_packed_unifi_sys_traffic_protocol_ind(uint8** resultBuffer, unifi_traffic_packettype packetType, unifi_protocol_direction direction, const unifi_MACAddress* srcAddress);
+extern uint16 build_packed_unifi_sys_ip_configured_ind(uint8** resultBuffer, Boolean ipConfigured);
+extern uint16 build_packed_unifi_sys_multicast_address_ind(uint8** resultBuffer, unifi_ListAction action, const unifi_MulticastAddressList* setAddresses);
+extern uint16 build_packed_unifi_sys_tclas_add_cfm(uint8** resultBuffer, unifi_Status status);
+extern uint16 build_packed_unifi_sys_tclas_del_cfm(uint8** resultBuffer, unifi_Status status);
+
+
+#endif /* __SYS_BUILD_FUNCTIONS_H__ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_remoteserver_to_sme_interface.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_remoteserver_to_sme_interface.c
new file mode 100644
index 0000000..26b147d
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_csr/sys_sap/sys_sap_remoteserver_to_sme_interface.c
@@ -0,0 +1,328 @@
+/* This is an autogenerated file from sme__remote_client_interface_c */
+/* Tag: noCheckHeader */
+
+/* CONFIDENTIAL */
+/* Copyright (C) Cambridge Silicon Radio Ltd 2008. All rights reserved. */
+
+/* This is an autogenerated file from sme__remote_client_interface_c.pl */
+
+
+#include "fsm/fsm.h"
+#include "fsm/fsm_types.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "smeio/smeio_fsm_events.h"
+#include "event_pack_unpack/event_pack_unpack.h"
+#include "sys_sap/sys_sap.h"
+#include "sys_sap/sys_sap_remote_sme_interface.h"
+
+static void event_to_unifi_sys_wifi_on_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ unifi_sys_wifi_on_req(context);
+
+}
+
+static void event_to_unifi_sys_wifi_on_rsp(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysWifiOnRsp_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.stationMacAddress.data, 6); /*lint !e545 !e725 uint8 : data */
+
+ unifi_sys_wifi_on_rsp(context, evt.status, &evt.stationMacAddress);
+
+}
+
+static void event_to_unifi_sys_wifi_off_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ unifi_sys_wifi_off_req(context);
+
+}
+
+static void event_to_unifi_sys_wifi_off_rsp(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ unifi_sys_wifi_off_rsp(context);
+
+}
+
+static void event_to_unifi_sys_suspend_rsp(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysSuspendRsp_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_sys_suspend_rsp(context, evt.status);
+
+}
+
+static void event_to_unifi_sys_resume_rsp(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysResumeRsp_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+
+ unifi_sys_resume_rsp(context, evt.status);
+
+}
+
+static void event_to_unifi_sys_hip_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysHipReq_Evt evt;
+ evt.mlmeCommand.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : mlmeCommand */
+ evt.mlmeCommand.data = NULL;
+ if (evt.mlmeCommand.length)
+ {
+ evt.mlmeCommand.data = (uint8*)osa_malloc(evt.mlmeCommand.length); /*lint !e725 unifi_DataBlock : mlmeCommand*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.mlmeCommand.data, evt.mlmeCommand.length); /*lint !e545 !e725 unifi_DataBlock : mlmeCommand */
+ }
+ evt.dataRef1.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : dataRef1 */
+ evt.dataRef1.data = NULL;
+ if (evt.dataRef1.length)
+ {
+ evt.dataRef1.data = (uint8*)osa_malloc(evt.dataRef1.length); /*lint !e725 unifi_DataBlock : dataRef1*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.dataRef1.data, evt.dataRef1.length); /*lint !e545 !e725 unifi_DataBlock : dataRef1 */
+ }
+ evt.dataRef2.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : dataRef2 */
+ evt.dataRef2.data = NULL;
+ if (evt.dataRef2.length)
+ {
+ evt.dataRef2.data = (uint8*)osa_malloc(evt.dataRef2.length); /*lint !e725 unifi_DataBlock : dataRef2*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.dataRef2.data, evt.dataRef2.length); /*lint !e545 !e725 unifi_DataBlock : dataRef2 */
+ }
+
+ unifi_sys_hip_req(context, &evt.mlmeCommand, &evt.dataRef1, &evt.dataRef2);
+
+ if (evt.mlmeCommand.length)
+ {
+ osa_free(evt.mlmeCommand.data); /*lint !e725 unifi_DataBlock : mlmeCommand*/
+ }
+ if (evt.dataRef1.length)
+ {
+ osa_free(evt.dataRef1.data); /*lint !e725 unifi_DataBlock : dataRef1*/
+ }
+ if (evt.dataRef2.length)
+ {
+ osa_free(evt.dataRef2.data); /*lint !e725 unifi_DataBlock : dataRef2*/
+ }
+}
+
+static void event_to_unifi_sys_qos_control_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysQosControlReq_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.control = event_unpack_uint16(&buffer); /* unifi_QoSControl : control */
+
+ unifi_sys_qos_control_req(context, evt.control);
+
+}
+
+static void event_to_unifi_sys_port_configure_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysPortConfigureReq_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.uncontrolledPortAction = event_unpack_uint16(&buffer); /* unifi_PortAction : uncontrolledPortAction */
+ /*lint -save -e545 -e725 */
+ evt.controlledPortAction = event_unpack_uint16(&buffer); /* unifi_PortAction : controlledPortAction */
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.macAddress.data, 6); /*lint !e545 !e725 uint8 : data */
+
+ unifi_sys_port_configure_req(context, evt.uncontrolledPortAction, evt.controlledPortAction, &evt.macAddress);
+
+}
+
+static void event_to_unifi_sys_configure_power_mode_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysConfigurePowerModeReq_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.mode = event_unpack_uint16(&buffer); /* unifi_LowPowerMode : mode */
+ /*lint -save -e545 -e725 */
+ evt.wakeHost = event_unpack_int16(&buffer); /* Boolean : wakeHost */
+
+ unifi_sys_configure_power_mode_req(context, evt.mode, evt.wakeHost);
+
+}
+
+static void event_to_unifi_sys_traffic_config_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysTrafficConfigReq_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.type = event_unpack_uint16(&buffer); /* unifi_traffic_configtype : type */
+ /*lint -save -e545 -e725 */
+ evt.config.packetFilter = event_unpack_uint16(&buffer); /* uint16 : packetFilter */
+ /*lint -save -e545 -e725 */
+ evt.config.customFilter.etherType = event_unpack_uint32(&buffer); /* uint32 : etherType */
+ /*lint -save -e545 -e725 */
+ evt.config.customFilter.ipType = event_unpack_uint8(&buffer); /* uint8 : ipType */
+ /*lint -save -e545 -e725 */
+ evt.config.customFilter.udpSourcePort = event_unpack_uint32(&buffer); /* uint32 : udpSourcePort */
+ /*lint -save -e545 -e725 */
+ evt.config.customFilter.udpDestPort = event_unpack_uint32(&buffer); /* uint32 : udpDestPort */
+
+ unifi_sys_traffic_config_req(context, evt.type, &evt.config);
+
+}
+
+static void event_to_unifi_sys_media_status_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysMediaStatusReq_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.mediaStatus = event_unpack_uint16(&buffer); /* unifi_MediaStatus : mediaStatus */
+
+ unifi_sys_media_status_req(context, evt.mediaStatus);
+
+}
+
+static void event_to_unifi_sys_multicast_address_rsp(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysMulticastAddressRsp_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.status = event_unpack_uint16(&buffer); /* unifi_Status : status */
+ /*lint -save -e545 -e725 */
+ evt.action = event_unpack_uint16(&buffer); /* unifi_ListAction : action */
+ /*lint -save -e545 -e725 */
+ evt.getAddresses.numElements = event_unpack_uint8(&buffer); /* uint8 : numElements */
+ evt.getAddresses.addresses = NULL;
+ if (evt.getAddresses.numElements)
+ {
+ int i;
+ evt.getAddresses.addresses = (unifi_MACAddress*)osa_malloc(sizeof(unifi_MACAddress) * evt.getAddresses.numElements);
+ for (i=0; i < evt.getAddresses.numElements; i++)
+ {
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, (uint8*)&evt.getAddresses.addresses[i].data, 6); /*lint !e545 !e725 uint8 : data */
+ }
+ }
+
+ unifi_sys_multicast_address_rsp(context, evt.status, evt.action, &evt.getAddresses);
+
+ if (evt.getAddresses.numElements)
+ {
+ int i;
+ for (i=0; i < evt.getAddresses.numElements; i++)
+ {
+ }
+ osa_free(evt.getAddresses.addresses);
+ }
+}
+
+static void event_to_unifi_sys_tclas_add_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysTclasAddReq_Evt evt;
+ evt.tclas.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : tclas */
+ evt.tclas.data = NULL;
+ if (evt.tclas.length)
+ {
+ evt.tclas.data = (uint8*)osa_malloc(evt.tclas.length); /*lint !e725 unifi_DataBlock : tclas*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.tclas.data, evt.tclas.length); /*lint !e545 !e725 unifi_DataBlock : tclas */
+ }
+
+ unifi_sys_tclas_add_req(context, &evt.tclas);
+
+ if (evt.tclas.length)
+ {
+ osa_free(evt.tclas.data); /*lint !e725 unifi_DataBlock : tclas*/
+ }
+}
+
+static void event_to_unifi_sys_tclas_del_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysTclasDelReq_Evt evt;
+ evt.tclas.length = event_unpack_uint16(&buffer); /*lint !e725 unifi_DataBlock : tclas */
+ evt.tclas.data = NULL;
+ if (evt.tclas.length)
+ {
+ evt.tclas.data = (uint8*)osa_malloc(evt.tclas.length); /*lint !e725 unifi_DataBlock : tclas*/
+ /*lint -save -e545 -e725 */
+ event_unpack_buffer(&buffer, evt.tclas.data, evt.tclas.length); /*lint !e545 !e725 unifi_DataBlock : tclas */
+ }
+
+ unifi_sys_tclas_del_req(context, &evt.tclas);
+
+ if (evt.tclas.length)
+ {
+ osa_free(evt.tclas.data); /*lint !e725 unifi_DataBlock : tclas*/
+ }
+}
+
+static void event_to_unifi_sys_traffic_classification_req(FsmContext* context, uint8* inputbuffer, uint16 size)
+{
+ uint8* buffer = &inputbuffer[6];
+ UnifiSysTrafficClassificationReq_Evt evt;
+ /*lint -save -e545 -e725 */
+ evt.type = event_unpack_uint16(&buffer); /* unifi_traffic_type : type */
+ /*lint -save -e545 -e725 */
+ evt.period = event_unpack_uint16(&buffer); /* uint16 : period */
+
+ unifi_sys_traffic_classification_req(context, evt.type, evt.period);
+
+}
+
+typedef void (*event_to_fn)(FsmContext* context, uint8* inputbuffer, uint16 size);
+static const event_to_fn fnlookup[31] = {
+ event_to_unifi_sys_wifi_on_req,
+ NULL,
+ event_to_unifi_sys_wifi_on_rsp,
+ NULL,
+ event_to_unifi_sys_wifi_off_req,
+ NULL,
+ event_to_unifi_sys_wifi_off_rsp,
+ NULL,
+ NULL,
+ event_to_unifi_sys_suspend_rsp,
+ NULL,
+ event_to_unifi_sys_resume_rsp,
+ event_to_unifi_sys_hip_req,
+ NULL,
+ event_to_unifi_sys_qos_control_req,
+ NULL,
+ event_to_unifi_sys_port_configure_req,
+ NULL,
+ event_to_unifi_sys_configure_power_mode_req,
+ event_to_unifi_sys_traffic_config_req,
+ NULL,
+ NULL,
+ NULL,
+ event_to_unifi_sys_media_status_req,
+ NULL,
+ event_to_unifi_sys_multicast_address_rsp,
+ event_to_unifi_sys_tclas_add_req,
+ NULL,
+ event_to_unifi_sys_tclas_del_req,
+ NULL,
+ event_to_unifi_sys_traffic_classification_req,
+};
+
+Boolean remote_sys_signal_receive(FsmContext* context, uint8* buffer, uint16 size)
+{
+ uint8* tempbuffer = buffer;
+ uint16 id = event_unpack_uint16(&tempbuffer);
+ uint16 idx = id - 0x8001;
+
+ if (idx < 31)
+ {
+ if (fnlookup[idx])
+ {
+ (*fnlookup[idx])(context, buffer, size);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_mgt.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_mgt.c
new file mode 100644
index 0000000..e1e3c42
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_mgt.c
@@ -0,0 +1,1026 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: sme_mgt.c
+ *
+ * PURPOSE:
+ * This file contains the driver specific implementation of
+ * the SME MGT SAP and implements the WEXT <==> SME MGT interface
+ * for all SME builds that support WEXT.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#include "driver/unifiversion.h"
+#include "unifi_priv.h"
+#include "driver/conversions.h"
+
+/*
+ * This file implements the SME MGT API. It contains the following functions:
+ * unifi_mgt_wifi_flightmode_cfm()
+ * unifi_mgt_wifi_on_cfm()
+ * unifi_mgt_wifi_off_cfm()
+ * unifi_mgt_wifi_off_ind()
+ * unifi_mgt_scan_full_cfm()
+ * unifi_mgt_scan_results_get_cfm()
+ * unifi_mgt_scan_result_ind()
+ * unifi_mgt_connect_cfm()
+ * unifi_mgt_media_status_ind()
+ * unifi_mgt_disconnect_cfm()
+ * unifi_mgt_key_cfm()
+ * unifi_mgt_multicast_address_cfm()
+ * unifi_mgt_set_value_cfm()
+ * unifi_mgt_get_value_cfm()
+ * unifi_mgt_mic_failure_ind()
+ * unifi_mgt_pmkid_cfm()
+ * unifi_mgt_pmkid_candidate_list_ind()
+ * unifi_mgt_mib_set_cfm()
+ * unifi_mgt_mib_get_cfm()
+ * unifi_mgt_mib_get_next_cfm()
+ * unifi_mgt_connection_quality_ind()
+ * unifi_mgt_packet_filter_set_cfm()
+ * unifi_mgt_tspec_cfm()
+ * unifi_mgt_tspec_ind()
+ */
+
+
+/*
+ * Handling the wext requests, we need to block
+ * until the SME sends the response to our request.
+ * We use the sme_init_request() and sme_wait_for_reply()
+ * to implement this behavior in the following functions:
+ * sme_mgt_wifi_on()
+ * sme_mgt_wifi_off()
+ * sme_mgt_scan_full()
+ * sme_mgt_scan_results_get_async()
+ * sme_mgt_connect()
+ * sme_mgt_disconnect()
+ * sme_mgt_pmkid()
+ * sme_mgt_key()
+ * sme_mgt_get_versions()
+ * sme_mgt_set_value_async()
+ * sme_mgt_get_value_async()
+ */
+
+
+
+void unifi_mgt_mic_failure_ind(void *drvpriv, Boolean secondFailure,
+ uint16 count, const unifi_MACAddress* address,
+ unifi_KeyType keyType, uint16 keyId,
+ const unifi_SequenceCount* tSC)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ CSR_MLME_MICHAELMICFAILURE_INDICATION mic_ind;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_mic_failure_ind: invalid priv\n");
+ return;
+ }
+
+ unifi_trace(priv, UDBG1,
+ "unifi_mgt_mic_failure_ind: count=%d, KeyType=%d, KeyId=%d\n",
+ count, keyType, keyId);
+
+ mic_ind.Count = count;
+ memcpy(mic_ind.Address.x, address->data, 6);
+ mic_ind.KeyType = keyType;
+ mic_ind.KeyId = keyId;
+ mic_ind.Tsc = UNPACK64(tSC->data, 0);
+
+ wext_send_michaelmicfailure_event(priv, &mic_ind);
+}
+
+
+void unifi_mgt_pmkid_cfm(void *drvpriv, unifi_Status status,
+ unifi_ListAction action,
+ const unifi_PmkidList* pmkids)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_pmkid_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ /*
+ * WEXT never does a GET operation the PMKIDs, so we don't need
+ * handle data returned in pmkids.
+ */
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_pmkid_candidate_list_ind(void *drvpriv,
+ const unifi_PmkidCandidateList* candidates)
+{
+}
+
+
+void unifi_mgt_scan_results_get_cfm(void *drvpriv, unifi_Status status,
+ const unifi_ScanResultList* resultsBuffer)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ int bytesRequired = resultsBuffer->numElements * sizeof(unifi_ScanResult);
+ int i;
+ uint8* current_buff;
+ unifi_ScanResultList scanCopy;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_scan_results_get_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ /* Calc the size of the buffer reuired */
+ for (i = 0; i < resultsBuffer->numElements; ++i) {
+ unifi_ScanResult *scan_result = &resultsBuffer->results[i];
+ bytesRequired += scan_result->informationElements.length;
+ }
+
+ /* Take a Copy of the scan Results :-) */
+ scanCopy.numElements = resultsBuffer->numElements;
+ scanCopy.results = unifi_malloc(priv, bytesRequired);
+ memcpy(scanCopy.results, resultsBuffer->results, sizeof(unifi_ScanResult)* scanCopy.numElements);
+
+ /* Take a Copy of the Info Elements AND update the scan result pointers */
+ current_buff = (uint8*)&scanCopy.results[scanCopy.numElements];
+ for (i = 0; i < scanCopy.numElements; ++i)
+ {
+ unifi_ScanResult *scan_result = &scanCopy.results[i];
+ osa_memcpy(current_buff, scan_result->informationElements.data, scan_result->informationElements.length);
+ scan_result->informationElements.data = current_buff;
+ current_buff += scan_result->informationElements.length;
+ }
+
+ priv->sme_reply.reply_scan_results = scanCopy;
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_scan_full_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_scan_full_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_scan_result_ind(void *drvpriv, const unifi_ScanResult* result)
+{
+
+}
+
+
+void unifi_mgt_connect_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_network_join_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_disconnect_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_disconnect_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_key_cfm(void *drvpriv, unifi_Status status,
+ unifi_ListAction action)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_key_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_multicast_address_cfm(void *drvpriv, unifi_Status status,
+ unifi_ListAction action,
+ const unifi_MulticastAddressList* addresses)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_multicast_address_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+void unifi_mgt_wifi_flightmode_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_wifi_flightmode_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+void unifi_mgt_wifi_on_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_wifi_on_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ unifi_trace(priv, UDBG4,
+ "unifi_mgt_wifi_on_cfm: wake up status %d\n", status);
+
+#if 0
+ sme_complete_request(priv, status);
+#endif
+
+}
+
+void unifi_mgt_wifi_off_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_wifi_off_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_wifi_off_ind(void *drvpriv, unifi_ControlIndication status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_sys_stopped_req: Invalid ospriv.\n");
+ return;
+ }
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "unifi_sys_stopped_req: invalid smepriv\n");
+ return;
+ }
+
+ /*
+ * If the status indicates an error, the SME is in a stopped state.
+ * We need to start it again in order to reinitialise UniFi.
+ */
+ switch (status) {
+ case unifi_Control_Error:
+ unifi_trace(priv, UDBG1,
+ "unifi_sys_stopped_req: Restarting SME (ind:%d)\n",
+ status);
+
+ /* On error, restart the SME */
+ sme_mgt_wifi_on(priv);
+ break;
+ case unifi_Control_Exit:
+ break;
+ default:
+ break;
+ }
+
+}
+
+
+void unifi_mgt_set_value_cfm(void *drvpriv, unifi_Status status,
+ unifi_AppValueId ValueId)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_set_value_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_mgt_get_value_cfm(void *drvpriv, unifi_Status status,
+ const unifi_AppValue* appValue)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_get_value_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ memcpy((unsigned char*)&priv->sme_reply.reply_app_value,
+ (unsigned char*)appValue,
+ sizeof(unifi_AppValue));
+
+ sme_complete_request(priv, status);
+}
+
+void unifi_mgt_mib_set_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_mib_set_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+void unifi_mgt_mib_get_cfm(void *drvpriv, unifi_Status status,
+ const unifi_DataBlock* mibAttributeValue)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_mib_get_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ if (mibAttributeValue == NULL) {
+ unifi_error(priv, "unifi_mgt_mib_get_cfm: Empty reply.\n");
+ sme_complete_request(priv, status);
+ return;
+ }
+
+ if ((priv->mib_cfm_buffer != NULL) &&
+ (priv->mib_cfm_buffer_length >= mibAttributeValue->length)) {
+ memcpy(priv->mib_cfm_buffer, mibAttributeValue->data, mibAttributeValue->length);
+ priv->mib_cfm_buffer_length = mibAttributeValue->length;
+ } else {
+ unifi_error(priv,
+ "unifi_mgt_mib_get_cfm: No room to store MIB data (have=%d need=%d).\n",
+ priv->mib_cfm_buffer_length, mibAttributeValue->length);
+ }
+
+ sme_complete_request(priv, status);
+}
+
+void unifi_mgt_mib_get_next_cfm(void *drvpriv, unifi_Status status,
+ const unifi_DataBlock* mibAttribute)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_mib_get_next_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ /* FIXME: Need to copy MIB data */
+
+ sme_complete_request(priv, status);
+}
+
+void unifi_mgt_connection_quality_ind(void *drvpriv, const unifi_ConnectionStats* connectionStats)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_connection_quality_ind: Invalid ospriv.\n");
+ return;
+ }
+
+ priv->wext_wireless_stats.qual.qual = connectionStats->unifiSNR;
+ priv->wext_wireless_stats.qual.level = connectionStats->unifiRSSI;
+ priv->wext_wireless_stats.qual.noise = connectionStats->unifiRSSI - connectionStats->unifiSNR;
+
+ priv->wext_wireless_stats.qual.updated = 0x7;
+
+ priv->cached_tx_rate = connectionStats->unifiTxDataRate;
+}
+
+void unifi_mgt_packet_filter_set_cfm(void *drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_packet_filter_set_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ /* The packet filter set request does not block for a reply */
+}
+
+void unifi_mgt_tspec_cfm(void* drvpriv, unifi_Status status,
+ uint32 transactionId,
+ unifi_TspecResultCode tspecResultCode,
+ const unifi_DataBlock* tspec)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_tspec_cfm: Invalid ospriv.\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+void unifi_mgt_tspec_ind(void* drvpriv, unifi_ListAction action, uint32 transactionId)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_mgt_tspec_ind: Invalid ospriv.\n");
+ return;
+ }
+
+
+}
+
+
+int sme_mgt_wifi_on(unifi_priv_t *priv)
+{
+/* sme_reply_t *sme_reply_ptr;
+ enum sme_request_status* request_status_ptr = NULL;
+ int r;*/
+ unifi_DataBlockList mib_data_list;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_wifi_on: invalid smepriv\n");
+ return -EIO;
+ }
+
+#if 0
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+#endif
+
+#ifdef CSR_SME_EMB
+ /*
+ * We need to read the MAC address, before we call unifi_mgt_wifi_on_req()
+ */
+ uf_request_mac_address_file(priv);
+#endif
+
+ if (priv->mib_data.length) {
+ mib_data_list.numElements = 1;
+ mib_data_list.datalist = &priv->mib_data;
+ } else {
+ mib_data_list.numElements = 0;
+ mib_data_list.datalist = NULL;
+ }
+ /* Start the SME */
+ unifi_mgt_wifi_on_req(priv->smepriv,
+ &priv->sta_mac_address,
+ &mib_data_list);
+ return 0;
+
+#if 0
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4,
+ "sme_mgt_wifi_on: unifi_mgt_wifi_on_req <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+#endif
+} /* sme_mgt_wifi_on() */
+
+
+int sme_mgt_wifi_off(unifi_priv_t *priv)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_wifi_off: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ /* Stop the SME */
+ unifi_mgt_wifi_off_req(priv->smepriv);
+
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4,
+ "sme_mgt_wifi_off: unifi_mgt_wifi_off_req <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+
+} /* sme_mgt_wifi_off */
+
+
+int sme_mgt_set_value_async(unifi_priv_t *priv, unifi_AppValue *app_value)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_set_value_async: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_set_value_req(priv->smepriv, app_value);
+
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG5,
+ "sme_mgt_set_value_async: unifi_mgt_set_value_req <-- (%d)\n",
+ r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+} /* sme_mgt_set_value_async() */
+
+
+int sme_mgt_get_value_async(unifi_priv_t *priv, unifi_AppValue *app_value)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_app_get_value: invalid smepriv\n");
+ return -EIO;
+ }
+
+ unifi_trace(priv, UDBG4, "sme_app_get_value: unifi_mgt_get_value_req -->\n");
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_get_value_req(priv->smepriv, app_value->id);
+
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ /* store the reply */
+ if (app_value != NULL) {
+ memcpy((unsigned char*)app_value,
+ (unsigned char*)&priv->sme_reply.reply_app_value,
+ sizeof(unifi_AppValue));
+ }
+
+ unifi_trace(priv, UDBG4, "sme_app_get_value: unifi_mgt_set_value_req <-- (%d)\n", r);
+
+ return convert_sme_error(priv->sme_reply.reply_status);
+} /* sme_mgt_get_value_async() */
+
+
+int sme_mgt_key(unifi_priv_t *priv, unifi_Key *sme_key,
+ enum unifi_ListAction action)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_key: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_key_req(priv->smepriv, action, sme_key);
+
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
+int sme_mgt_scan_full(unifi_priv_t *priv, unifi_SSID *specific_ssid)
+{
+ static const unifi_DataBlock empty_data_block = {0, NULL};
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_scan_full: invalid smepriv\n");
+ return -EIO;
+ }
+
+ unifi_trace(priv, UDBG4, "sme_mgt_scan_full: -->\n");
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_scan_full_req(priv->smepriv,
+ specific_ssid,
+ FALSE,
+ unifi_ScanAll,
+ &empty_data_block);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4, "sme_mgt_scan_full: <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
+int sme_mgt_scan_results_get_async(unifi_priv_t *priv,
+ struct iw_request_info *info,
+ char *scan_results,
+ long scan_results_len)
+{
+ unifi_ScanResultList scan_result_list;
+ unifi_ScanResult *scan_result;
+ int r;
+ int i;
+ char *current_ev = scan_results;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_scan_results_get_async: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_scan_results_get_req(priv->smepriv);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ scan_result_list = priv->sme_reply.reply_scan_results;
+ unifi_trace(priv, UDBG2,
+ "scan_results: Scan returned %d, numElements=%d\n",
+ r, scan_result_list.numElements);
+
+ /* OK, now we have the scan results */
+ for (i = 0; i < scan_result_list.numElements; ++i) {
+ scan_result = &scan_result_list.results[i];
+
+ unifi_trace(priv, UDBG2, "Scan Result: %.*s\n",
+ scan_result->ssid.length,
+ scan_result->ssid.ssid);
+
+ r = unifi_translate_scan(priv->netdev, info,
+ current_ev,
+ scan_results + scan_results_len,
+ scan_result, i+1);
+ if (r < 0) {
+ unifi_free(priv, scan_result_list.results);
+ priv->sme_reply.reply_scan_results.numElements = 0;
+ priv->sme_reply.reply_scan_results.results = NULL;
+ return r;
+ }
+
+ current_ev += r;
+ }
+
+ /*
+ * Free the scan results allocated in unifi_mgt_scan_results_get_cfm()
+ * and invalidate the reply_scan_results to avoid re-using
+ * the freed pointers.
+ */
+ unifi_free(priv, scan_result_list.results);
+ priv->sme_reply.reply_scan_results.numElements = 0;
+ priv->sme_reply.reply_scan_results.results = NULL;
+
+ unifi_trace(priv, UDBG2,
+ "scan_results: Scan translated to %d bytes\n",
+ current_ev - scan_results);
+ return (current_ev - scan_results);
+}
+
+
+int sme_mgt_connect(unifi_priv_t *priv)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_connect: invalid smepriv\n");
+ return -EIO;
+ }
+
+ unifi_trace(priv, UDBG2, "sme_mgt_connect: %.*s\n",
+ priv->connection_config.ssid.length,
+ priv->connection_config.ssid.ssid);
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_connect_req(priv->smepriv, &priv->connection_config);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ if (priv->sme_reply.reply_status) {
+ unifi_trace(priv, UDBG1, "sme_mgt_connect: failed with SME status %d\n",
+ priv->sme_reply.reply_status);
+ }
+
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
+void unifi_mgt_media_status_ind(void *drvpriv,
+ unifi_MediaStatus mediaStatus,
+ const unifi_ConnectionInfo* connection_info)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "unifi_mgt_media_status_ind: invalid smepriv\n");
+ return;
+ }
+
+ if (mediaStatus == unifi_MediaConnected) {
+ /*
+ * Send wireless-extension event up to userland to announce
+ * connection.
+ */
+ wext_send_assoc_event(priv,
+ (unsigned char *)connection_info->assocReqApAddress.data,
+ (unsigned char *)connection_info->assocReqInfoElements.data,
+ connection_info->assocReqInfoElements.length,
+ (unsigned char *)connection_info->assocRspInfoElements.data,
+ connection_info->assocRspInfoElements.length,
+ (unsigned char *)connection_info->assocScanInfoElements.data,
+ connection_info->assocScanInfoElements.length);
+
+ sme_mgt_packet_filter_set(priv);
+
+ } else {
+ /*
+ * Send wireless-extension event up to userland to announce
+ * connection lost to a BSS.
+ */
+ wext_send_disassoc_event(priv);
+ }
+}
+
+
+int sme_mgt_disconnect(unifi_priv_t *priv)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_disconnect: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_disconnect_req(priv->smepriv);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4, "sme_mgt_disconnect: <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
+int sme_mgt_pmkid(unifi_priv_t *priv,
+ unifi_ListAction action,
+ unifi_PmkidList *pmkid_list)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_pmkid: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_pmkid_req(priv->smepriv, action, pmkid_list);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4, "sme_mgt_pmkid: <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
+int sme_mgt_mib_get(unifi_priv_t *priv,
+ unsigned char *varbind, int *length)
+{
+ int r;
+ unifi_DataBlock sme_data_block;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ sme_data_block.data = varbind;
+ sme_data_block.length = *length;
+ priv->mib_cfm_buffer = varbind;
+ priv->mib_cfm_buffer_length = MAX_VARBIND_LENGTH;
+
+ unifi_mgt_mib_get_req(priv->smepriv, &sme_data_block);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ priv->mib_cfm_buffer_length = 0;
+ priv->mib_cfm_buffer = NULL;
+ return r;
+ }
+
+ *length = priv->mib_cfm_buffer_length;
+
+ priv->mib_cfm_buffer_length = 0;
+ priv->mib_cfm_buffer = NULL;
+ unifi_trace(priv, UDBG4, "sme_mgt_mib_get: <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+int sme_mgt_mib_set(unifi_priv_t *priv,
+ unsigned char *varbind, int length)
+{
+ int r;
+ unifi_DataBlock sme_data_block;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ sme_data_block.data = varbind;
+ sme_data_block.length = length;
+
+ unifi_mgt_mib_set_req(priv->smepriv, &sme_data_block);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4, "sme_mgt_mib_set: <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
+
+int sme_mgt_get_versions(unifi_priv_t *priv, unifi_Versions *versions)
+{
+ unifi_AppValue sme_app_value;
+ int r;
+
+ sme_app_value.id = unifi_VersionsValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv,
+ "sme_mgt_get_versions: Failed to get unifi_VersionsValue.\n");
+ return r;
+ }
+
+ memcpy(versions, &sme_app_value.unifi_Value_union.versions, sizeof(unifi_Versions));
+
+ return 0;
+}
+
+
+int sme_mgt_get_value(unifi_priv_t *priv, unifi_AppValue *app_value)
+{
+ unifi_Status status;
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_get_value: invalid smepriv\n");
+ return -EIO;
+ }
+
+#ifdef CSR_SME_USERSPACE
+ status = sme_mgt_get_value_async(priv->smepriv, app_value);
+#else
+ /* FIXME : This needs some rework as the
+ * buffers in app_value need to be copied */
+ unifi_mgt_claim_sync_access(priv->smepriv);
+ status = unifi_mgt_get_value(priv->smepriv, app_value);
+ unifi_mgt_release_sync_access(priv->smepriv);
+#endif
+ return status;
+} /* sme_mgt_get_value() */
+
+
+int sme_mgt_set_value(unifi_priv_t *priv, unifi_AppValue *app_value)
+{
+ unifi_Status status;
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_set_value: invalid smepriv\n");
+ return -EIO;
+ }
+#ifdef CSR_SME_USERSPACE
+ status = sme_mgt_set_value_async(priv->smepriv, app_value);
+#else
+ unifi_mgt_claim_sync_access(priv->smepriv);
+ status = unifi_mgt_set_value(priv->smepriv, app_value);
+ unifi_mgt_release_sync_access(priv->smepriv);
+#endif
+ return status;
+} /* sme_mgt_set_value() */
+
+
+int sme_mgt_packet_filter_set(unifi_priv_t *priv)
+{
+ unifi_DataBlock filter;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n");
+ return -EIO;
+ }
+
+ filter.data = priv->filter_tclas_ies;
+ filter.length = priv->packet_filters.tclas_ies_length;
+ unifi_mgt_packet_filter_set_req(priv->smepriv, &filter,
+ priv->packet_filters.filter_mode,
+ (priv->packet_filters.arp_filter ? priv->sta_ip_address : 0xFFFFFFFF));
+ return 0;
+}
+
+
+int sme_mgt_tspec(unifi_priv_t *priv, unifi_ListAction action,
+ uint32 tid, unifi_DataBlock *tspec, unifi_DataBlock *tclas)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_mgt_tspec_req(priv->smepriv, action, tid, TRUE,
+ tspec, tclas);
+ r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
+ if (r) {
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/autojoin.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/autojoin.c
new file mode 100644
index 0000000..1b2585e
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/autojoin.c
@@ -0,0 +1,1580 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: autojoin.c
+ *
+ * PURPOSE:
+ * This file provides the "autojoin" functionality required for linux
+ * wireless extensions.
+ * It is effeectively a very, very simple SME.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+#if 0
+#undef func_enter
+#undef func_exit
+#define func_enter() printk("=> %s\n", __FUNCTION__)
+#define func_exit() printk("<= %s\n", __FUNCTION__)
+#endif
+
+/* The additional time taken by the UniFi to do a scan per channel */
+#define SCAN_STARTUP_TIME 300 /* in millisecs */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_do_scan
+ *
+ * Convenience function to perform a scan to list all networks
+ * in the vicinity.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ * scantype 0 = active, 1 = passive
+ * bsstype What sort of networks to scan for:
+ * 0 = Infra, 1 = IBSS, 2 = Any
+ * ssid Pointer to a network name (ESSID) to scan for, or
+ * NULL to scan for all networks.
+ * ssid_len Length of ssid.
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ *
+ * Notes:
+ * Parameters we could add:
+ * channel The channel number to scan on or -1 meaning scan
+ * all channels
+ * For a really quick scan we could scan a particular channel.
+ * Also:
+ * bssid MAC address of network to scan for, or NULL
+ * ssid Network name to scan for, or NULL
+ * but these won't reduce the scan time at all, so there's no point
+ * in using them.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_do_scan(unifi_priv_t *priv, int scantype, CSR_BSS_TYPE bsstype,
+ const char *ssid, int ssid_len)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_SCAN_REQUEST *req = &signal.u.MlmeScanRequest;
+ bulk_data_param_t data_ptrs;
+ int r, rc;
+ unsigned char *ie_buf = NULL;
+ unsigned int ie_len = 0;
+ unsigned long j;
+ int timeout = 1000;
+ int num_channels = 11;
+ ul_client_t *pcli = priv->wext_client;
+
+ /* clear the pre-existing scan results */
+ unifi_clear_scan_table(priv);
+
+ unifi_notice(priv, "Scanning for wireless networks\n");
+
+ memset((void*)req, 0, sizeof(req));
+
+ req->Ifindex = priv->if_index; /* 2.4GHz or 5GHz operation */
+ req->BssType = bsstype;
+ memset((void*)req->Da.x, 0xFF, 6);
+ memset((void*)req->Bssid.x, 0xFF, 6);
+ req->ScanType = scantype; /* 0 = active, 1 = passive */
+ if (scantype == UNIFI_SCAN_ACTIVE) {
+ /* Use shorter times for an active scan */
+ req->ProbeDelay = 10;
+ req->MinChannelTime = 50;
+ req->MaxChannelTime = 150;
+ } else {
+ req->ProbeDelay = 0;
+ req->MinChannelTime = 200;
+ req->MaxChannelTime = 250;
+ }
+
+ /* Figure out our timeout ms */
+ timeout = num_channels * (req->MaxChannelTime +
+ req->ProbeDelay +
+ SCAN_STARTUP_TIME);
+ timeout += timeout / 2;/* add 50% */
+
+ /* Build Information Elements for a bulk data slot */
+
+ /* If SSID is given, add it to the IE vector */
+ if (ssid && ssid_len) {
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[1], ssid_len + 2);
+ if (r != 0) {
+ unifi_error(priv, "unifi_do_scan: failed to allocate ie_buf.\n");
+ return -EIO;
+ }
+ ie_buf = (unsigned char*)data_ptrs.d[1].os_data_ptr;
+ unifi_add_info_element(ie_buf, IE_SSID_ID, ssid, ssid_len);
+ ie_len = ssid_len + 2;
+ }
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SCAN_REQUEST_ID;
+
+ data_ptrs.d[0].os_data_ptr = data_ptrs.d[0].os_net_buf_ptr = NULL;
+ data_ptrs.d[0].data_length = 0;
+ /* Do not mess with data_ptrs.d[1].os_net_buf_ptr. */
+ data_ptrs.d[1].os_data_ptr = ie_buf;
+ data_ptrs.d[1].data_length = ie_len;
+
+ j = jiffies;
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r) {
+ unifi_error(priv, "failed to send SCAN request, error %d\n", r);
+ return r;
+ }
+
+ rc = pcli->reply_signal->u.MlmeScanConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "SCAN request was rejected with with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ return -EIO;
+ }
+
+ unifi_trace(priv, UDBG1, "Scan time %ld jiffies\n", jiffies - j);
+
+ return 0;
+} /* unifi_do_scan() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_do_join
+ *
+ * Join a BSS whose BSS description was previously obtained with
+ * a scan.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ * si Pointer to scan info struct for BSS to join.
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_do_join(unifi_priv_t *priv, scan_info_t *si)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_JOIN_REQUEST *req = &signal.u.MlmeJoinRequest;
+ bulk_data_param_t data_ptrs;
+ struct wext_config *conf= &priv->wext_conf;
+ int timeout;
+ int r, rc;
+ ul_client_t *pcli = priv->wext_client;
+ unsigned char *scan_ie_buf = NULL;
+ unsigned int scan_ie_len = 0;
+
+ unifi_trace(priv, UDBG1, "Join: bssid=%02X:%02X:%02X:%02X:%02X:%02X, capability=0x%X, channel=%d\n",
+ si->msi.Bssid.x[0], si->msi.Bssid.x[1], si->msi.Bssid.x[2],
+ si->msi.Bssid.x[3], si->msi.Bssid.x[4], si->msi.Bssid.x[5],
+ si->msi.CapabilityInformation, si->msi.Channel);
+
+ /*
+ * Set up the JOIN request
+ * req.JoinFailureTimeout is in BeaconPeriods. We make the assumption that an
+ * 802.11 TU (1024us) is approximately 1ms, the units used for
+ * conf->join_failure_timeout.
+ */
+ req->Ifindex = si->msi.Ifindex;
+ memcpy((void*)req->Bssid.x, (void*)si->msi.Bssid.x, 6);
+ req->BeaconPeriod = si->msi.BeaconPeriod;
+ req->Timestamp = si->msi.Timestamp;
+ req->LocalTime = si->msi.LocalTime;
+ req->Channel = si->msi.Channel;
+ req->CapabilityInformation = si->msi.CapabilityInformation;
+ req->JoinFailureTimeout = conf->join_failure_timeout / si->msi.BeaconPeriod;
+ req->ProbeDelay = 0;
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_JOIN_REQUEST_ID;
+
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], si->info_elem_length);
+ if (r != 0) {
+ unifi_error(priv, "unifi_do_join: failed to allocate scan_ie_buf.\n");
+ return -EIO;
+ }
+ scan_ie_buf = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ memcpy(scan_ie_buf, si->info_elems, si->info_elem_length);
+ scan_ie_len = si->info_elem_length;
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = scan_ie_buf;
+ data_ptrs.d[0].data_length = scan_ie_len;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ /*
+ * Calculate a suitable transport timeout.
+ * Use the operation timeout plus 50%.
+ */
+ timeout = conf->join_failure_timeout + (conf->join_failure_timeout/2);
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r) {
+ unifi_error(priv, "failed to send JOIN request, error %d\n", r);
+ return r;
+ }
+
+ rc = pcli->reply_signal->u.MlmeJoinConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "JOIN requestwas rejected with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ return -EIO;
+ }
+
+ /* Copy BSSID and capability to wireless conf struct */
+ memcpy((void*)priv->wext_conf.current_bssid, (void*)si->msi.Bssid.x, 6);
+ priv->wext_conf.capability = si->msi.CapabilityInformation;
+ priv->wext_conf.channel = si->msi.Channel;
+
+ func_exit();
+ return 0;
+} /* unifi_do_join() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_do_start
+ *
+ * Start an adhoc network using the parameters in priv->wext_conf.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_do_start(unifi_priv_t *priv, const char *ssid)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_START_REQUEST *req = &signal.u.MlmeStartRequest;
+ bulk_data_param_t data_ptrs;
+ struct wext_config *conf= &priv->wext_conf;
+ int timeout = 2000;
+ int r, rc;
+ int capability;
+ int ssid_len;
+ static const unsigned char supp_rates[] = {
+ 0x82, 0x84, 0x8B, 0x96, 12, 24, 48, 72, 18, 36, 96, 108
+ };
+ const int num_supp_rates = sizeof(supp_rates);
+ ul_client_t *pcli = priv->wext_client;
+ unsigned char *ie_buf = NULL;
+ unsigned int ie_len = 0;
+
+ /* Build the capability word */
+ capability = SIG_CAP_SHORT_PREAMBLE;
+
+ if (conf->mode == IW_MODE_INFRA) {
+ capability |= SIG_CAP_ESS;
+ } else {
+ capability |= SIG_CAP_IBSS;
+ }
+ if (conf->privacy) {
+ capability |= SIG_CAP_PRIVACY;
+ }
+
+ /*
+ * If the user has not selected a valid channel, we will start in
+ * channel 10 or channel 52 (802.11a)
+ */
+ if (conf->channel <= 0) {
+ if (priv->if_index == CSR_INDEX_5G) {
+ conf->channel = 52;
+ } else {
+ conf->channel = 10;
+ }
+ }
+
+ unifi_trace(priv, UDBG1, "start: capability=0x%X, chan=%d, beacon=%d, ssid=\"%s\"\n",
+ capability, conf->channel, conf->beacon_period, ssid);
+
+
+ /*
+ * Build the InformationElements
+ */
+ ssid_len = strlen(ssid);
+ ie_len = ssid_len + num_supp_rates + ((capability & SIG_CAP_IBSS) ? 2 : 0);
+ if (ie_len) {
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], ie_len);
+ if (r != 0) {
+ unifi_error(priv, "unifi_do_start: failed to allocate ie_buf.\n");
+ return -EIO;
+ }
+ ie_buf = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ /* If SSID is given, add it top the IE vector */
+ if (ssid_len) {
+ unifi_add_info_element(ie_buf, IE_SSID_ID, ssid, ssid_len);
+ ie_len = ssid_len + 2;
+ }
+
+ if (num_supp_rates <= 8) {
+ unifi_add_info_element(ie_buf + ie_len,
+ IE_SUPPORTED_RATES_ID, supp_rates, num_supp_rates);
+ ie_len += num_supp_rates + 2;
+ } else {
+ unifi_add_info_element(ie_buf + ie_len,
+ IE_SUPPORTED_RATES_ID, supp_rates, 8);
+ ie_len += 8 + 2;
+ }
+
+#if 0
+ /* is this needed? */
+ {
+ unsigned char buf[4];
+ buf[0] = conf->channel;
+ INFO_ELEM_ADD(IE_DS_PARAM_SET_ID, buf, 1);
+ }
+#endif
+
+#if 0
+ /* For AP mode, which is not yet supported */
+ /* If an ESS, add a TIM elememt with DTIM Count = 0 to set the DTIM Period. */
+ if (capability & SIG_CAP_ESS)
+ {
+ unsigned char buf[8];
+ buf[0] = 0; /* DTIM Count */
+ buf[1] = conf->dtim_period; /* DTIM Period */
+ buf[2] = 0; /* Bitmap Control */
+ buf[3] = 0; /* Partial Virtual Bitmap */
+ INFO_ELEM_ADD(IE_TIM_ID, buf, 4);
+ }
+#endif
+
+
+ /*
+ * In an IBSS, UniFi requires an ATIM Window paramter, which is specified
+ * in the IBSS Parm Set information element
+ * Use the value from the user if given, else use a default of 10% of
+ * Beacon period.
+ */
+ if (capability & SIG_CAP_IBSS) {
+ int atim;
+ unsigned char buf[8];
+
+ atim = conf->beacon_period / 10;
+
+ buf[0] = atim & 0xFF;
+ buf[1] = (atim >> 8) & 0xFF;
+ unifi_add_info_element(ie_buf + ie_len, IE_IBSS_PARAM_SET_ID, buf, 2);
+ ie_len += 2 + 2;
+ }
+
+ /* This comes here so that IE ids are in numeric sequence */
+ if (num_supp_rates > 8) {
+ unifi_add_info_element(ie_buf + ie_len, IE_EXTENDED_SUPPORTED_RATES_ID,
+ supp_rates + 8, num_supp_rates - 8);
+ ie_len += num_supp_rates - 8 + 2;
+ }
+ }
+
+ /*
+ * Build the request
+ */
+ memset((void*)req, 0, sizeof(req));
+
+ req->Ifindex = priv->if_index; /* 2.4GHz or 5GHz operation */
+
+ req->BeaconPeriod = conf->beacon_period;
+ req->Channel = conf->channel;
+ req->ProbeDelay = 100;
+ req->CapabilityInformation = capability;
+
+ /* Reset the f/w 802.11 state */
+ r = unifi_reset_state(priv, priv->netdev->dev_addr, 0);
+ if (r) {
+ unifi_notice(priv, "Failed to reset device\n");
+ func_exit();
+ return r;
+ }
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_START_REQUEST_ID;
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = ie_buf;
+ data_ptrs.d[0].data_length = ie_len;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r) {
+ unifi_error(priv, "failed to send START request, error %d\n", r);
+ return r;
+ }
+
+ rc = pcli->reply_signal->u.MlmeStartConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "START request was rejected with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ return -EIO;
+ }
+
+ /* Copy BSSID and SSID to wireless conf struct */
+ memcpy((void*)priv->wext_conf.current_bssid,
+ (void*)pcli->reply_signal->u.MlmeStartConfirm.Bssid.x, 6);
+ strncpy(priv->wext_conf.current_ssid, ssid, UNIFI_MAX_SSID_LEN);
+
+ func_exit();
+ return 0;
+} /* unifi_do_start() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_do_authenticate
+ *
+ * Send a MLME-AUTHENTICATE.request to UniFi to begin an
+ * authentication exchange.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_do_authenticate(unifi_priv_t *priv)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_AUTHENTICATE_REQUEST *req = &signal.u.MlmeAuthenticateRequest;
+ struct wext_config *conf= &priv->wext_conf;
+ int timeout;
+ int r, rc;
+ ul_client_t *pcli = priv->wext_client;
+
+ func_enter();
+
+ unifi_trace(priv, UDBG1, "auth: type=%d, bssid=%02X:%02X:%02X:%02X:%02X:%02X\n",
+ conf->auth_type,
+ priv->wext_conf.current_bssid[0], priv->wext_conf.current_bssid[1],
+ priv->wext_conf.current_bssid[2], priv->wext_conf.current_bssid[3],
+ priv->wext_conf.current_bssid[4], priv->wext_conf.current_bssid[5]);
+
+ memcpy((void*)req->PeerStaAddress.x, (void*)priv->wext_conf.current_bssid, 6);
+ req->AuthenticationType = conf->auth_type;
+ req->AuthenticationFailureTimeout = host2unifi_16(conf->auth_failure_timeout);
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_AUTHENTICATE_REQUEST_ID;
+
+ /*
+ * Calculate a suitable transport timeout.
+ * Use the operation timeout plus 50%.
+ */
+ timeout = conf->auth_failure_timeout + conf->auth_failure_timeout/2;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, NULL, timeout);
+ if (r) {
+ unifi_error(priv, "failed to send AUTHENTICATE request, error %d\n", r);
+ return r;
+ }
+
+ rc = pcli->reply_signal->u.MlmeAuthenticateConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "AUTHENTICATE request was rejected with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ return -EIO;
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_do_authenticate() */
+
+
+
+#define WMM_IE_QOS_INFO_OFFSET 8
+
+/*
+ * ---------------------------------------------------------------------------
+ * get_wmm_bss_capabilities
+ *
+ * Searches for the WMM IE in the IEs buffer
+ *
+ * Arguments:
+ * ie_vector Pointer to the buffer containing the IEs.
+ * ie_len Size of the buffer
+ *
+ * Returns:
+ * 1 on success, 0 on failure
+ * ---------------------------------------------------------------------------
+ */
+static unsigned int
+get_wmm_bss_capabilities(unifi_priv_t *priv, unsigned char *ie_vector, int ie_len, int *ap_capabilities)
+{
+ int tmp_ie_len = ie_len;
+ const unsigned char *tmp_ie_ptr = ie_vector;
+ const unsigned char *elem;
+ unsigned int fiematch = 0;
+ const unsigned char wmm_oui[4] = {0x00, 0x50, 0xF2, 0x02};
+
+ *ap_capabilities = 0;
+ /* Search for this IE in the buffer. */
+ while (tmp_ie_len > 0)
+ {
+ /* Get the first matching element */
+ elem = unifi_find_info_element(221, tmp_ie_ptr, tmp_ie_len);
+ /* if the id does not exist we just want to get out of while loop */
+ if (elem) {
+ /* match the oui, etc */
+ if ((memcmp(elem+2, wmm_oui, 4) == 0) &&
+ ((elem[6] == 0x00) || (elem[6] == 0x01)))
+ {
+ fiematch = 1;
+ *ap_capabilities |= QOS_CAPABILITY_WMM_ENABLED;
+ if (elem[WMM_IE_QOS_INFO_OFFSET] & 0x80) {
+ unifi_trace(priv, UDBG3, "WMM: Peer has U-APSD flag anabled.\n");
+ *ap_capabilities |= QOS_CAPABILITY_WMM_UAPSD;
+ }
+ /* If it is a parameter IE we need to search for admission control */
+ if ((elem[6] == 0x01) && (elem[1] >= 24)) {
+ int i;
+ for (i=10; i<23; i=i+4) {
+ if (elem[i] & 0x10) {
+ switch (elem[i] & 0x60) {
+ case 0x00:
+ *ap_capabilities |= QOS_CAPABILITY_ACM_BE_ENABLED;
+ break;
+ case 0x20:
+ *ap_capabilities |= QOS_CAPABILITY_ACM_BK_ENABLED;
+ break;
+ case 0x40:
+ *ap_capabilities |= QOS_CAPABILITY_ACM_VI_ENABLED;
+ break;
+ case 0x60:
+ *ap_capabilities |= QOS_CAPABILITY_ACM_VO_ENABLED;
+ break;
+ default:
+ unifi_error(priv, "Unrecognised WMM ACI parameter.\n");
+ break;
+ }
+ }
+ }
+ }
+ tmp_ie_len = 0;
+ }
+
+ /* if they match we just want to get out of while loop */
+ if (!fiematch) {
+ /* advance to the next IE in the buffer */
+ tmp_ie_len -= (elem - tmp_ie_ptr) + elem[1] + 2;
+ tmp_ie_ptr = elem + (elem[1] + 2);
+ }
+ } else {
+ tmp_ie_len = 0;
+ }
+ }
+ return fiematch;
+} /* get_wmm_bss_capabilities() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_wmm_traffic_streams
+ *
+ * Sends TSPEC WMM request for any AC that has Admission Control enabled.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ *
+ * Returns:
+ *
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_wmm_traffic_streams(unifi_priv_t *priv)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_ADDTS_REQUEST *req = &signal.u.MlmeAddtsRequest;
+ bulk_data_param_t data_ptrs;
+ ul_client_t *pcli = priv->wext_client;
+ int i, r = 0, rc;
+ static const int timeout = 5000;
+ static unsigned char psb;
+ unsigned char *tspec_ie = NULL;
+
+ const static unsigned char _tspec_ie[] = {
+ 0xDD, 61,
+ 0x00, 0x50, 0xF2, 0x02, 0x02, 0x01,
+ 0xE0, 0x00, 0x00, /* TS Info Field (Bi-directional)*/
+ 0xD0, 0x80, /* Nominal MSDU Size */
+ 0x00, 0x00, /* Maximum MSDU Size */
+ 0x20, 0x4e, 0x00, 0x00, /* Minimum Service Interval */
+ 0x20, 0x4e, 0x00, 0x00, /* Maximum Service Interval */
+ 0x00, 0x00, 0x00, 0x00, /* Inactivity Interval */
+ 0x00, 0x00, 0x00, 0x00, /* Suspension Interval */
+ 0x00, 0x00, 0x00, 0x00, /* Service Start Time (if APSD=0 then this is 0)*/
+ 0x00, 0x00, 0x00, 0x00, /* Minimum Data Rate */
+ 0x00, 0x45, 0x01, 0x00, /* Mean Data Rate */
+ 0x00, 0x00, 0x00, 0x00, /* Peak Data Rate */
+ 0x00, 0x00, 0x00, 0x00, /* Burst Size (No bursts) */
+ 0x00, 0x00, 0x00, 0x00, /* Delay Bound */
+ 0x80, 0x8D, 0x5B, 0x00, /* Minimum PHY Rate */
+ 0x00, 0x24, /* Surplus Bandwidth Allowance */
+ 0x00, 0x00 /* Medium Time */
+ };
+
+ /* Allow a reasonable period between the failure timeout and our request's timeout. */
+ req->AddtsFailureTimeout = timeout/2;
+ for (i = 0; i < 4; i++) {
+ if (priv->wext_conf.bss_wmm_capabilities & (QOS_CAPABILITY_ACM_BE_ENABLED << i)) {
+
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], 63);
+ if (r != 0) {
+ unifi_error(priv, "set_wmm_traffic_streams: failed to allocate tspec_ie.\n");
+ return -EIO;
+ }
+ tspec_ie = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ memcpy(tspec_ie, _tspec_ie, 63);
+
+ if (priv->wext_conf.wmm_bss_uapsd_mask & (0x01 << i)) {
+ psb = 0x04;
+ } else {
+ psb = 0;
+ }
+
+ req->DialogToken = 1 << i;
+ switch (i) {
+ case 1: /* ac_bk */
+ tspec_ie[8] = 0xE0 | 0x02;
+ tspec_ie[9] = psb | 0x08;
+ tspec_ie[11] = 0x96;
+ tspec_ie[39] = 0x00;
+ tspec_ie[40] = 0x08;
+ tspec_ie[41] = 0x00;
+ break;
+ case 3: /* ac_vo */
+ tspec_ie[8] = 0xE0 | (i << 2);
+ tspec_ie[9] = psb | (i << 4);
+ tspec_ie[11] = 0xD0;
+ tspec_ie[39] = 0x00;
+ tspec_ie[40] = 0x45;
+ tspec_ie[41] = 0x01;
+ break;
+ case 0: /* ac_be */
+ case 2: /* ac_vi */
+ tspec_ie[8] = 0xE0 | (i << 2);
+ tspec_ie[9] = psb | (i << 4);
+ tspec_ie[11] = 0x96;
+ tspec_ie[39] = 0x00;
+ tspec_ie[40] = 0x08;
+ tspec_ie[41] = 0x00;
+ break;
+ }
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_ADDTS_REQUEST_ID;
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = tspec_ie;
+ data_ptrs.d[0].data_length = 63;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ /* Send an MLME-ADDTS.req */
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send ADDTS request, error %d\n", r);
+ return -EIO;
+ }
+
+ rc = pcli->reply_signal->u.MlmeAddtsConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "ADDTS request was rejected with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ }
+
+ /* If the reply is successful, enable the TS for this AC */
+ if (rc == CSR_RC_SUCCESS) {
+ priv->sta_wmm_capabilities |= (QOS_CAPABILITY_TS_BE_ENABLED << i);
+ }
+ }
+ }
+
+ return 0;
+} /* set_wmm_traffic_streams() */
+
+#define WMM_IE_SIZE 9
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_do_associate
+ *
+ * Associate with an ESS.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ * si Pointer to the scan information of the selected BSSID
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_do_associate(unifi_priv_t *priv, scan_info_t *si)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_ASSOCIATE_REQUEST *req = &signal.u.MlmeAssociateRequest;
+ bulk_data_param_t data_ptrs;
+ struct wext_config *conf= &priv->wext_conf;
+ ul_client_t *pcli = priv->wext_client;
+ int timeout;
+ int r, rc;
+ unsigned char ie_confirm_vector[IE_VECTOR_MAXLEN];
+ int ie_confirm_len;
+ unsigned char wmm_ie[] = {
+ 0xDD, 0x07, 0x00, 0x50, 0xF2, 0x02, 0x00, 0x01, 0x00
+ };
+ unsigned char *ie_request_buf = NULL;
+ unsigned int ie_request_len = 0;
+ unsigned char append_wmm_ie = 0;
+
+ func_enter();
+
+ unifi_trace(priv, UDBG1, "assoc: bssid=%02X:%02X:%02X:%02X:%02X:%02X, listen=%d, timeout=%d\n",
+ priv->wext_conf.current_bssid[0], priv->wext_conf.current_bssid[1],
+ priv->wext_conf.current_bssid[2], priv->wext_conf.current_bssid[3],
+ priv->wext_conf.current_bssid[4], priv->wext_conf.current_bssid[5],
+ conf->assoc_listen_interval,
+ conf->assoc_failure_timeout);
+
+ /*
+ * If the AP supports QOS (WMM) we have to add the WMM IE to our
+ * association request. We temporary use the buffer comming from the
+ * wireless extensions. Note that we just append the WMM IE, without
+ * modifying the length we know for the data in the buffer.
+ */
+ if (priv->wext_conf.bss_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) {
+ if ((WMM_IE_SIZE + conf->generic_ie_len) <= IE_VECTOR_MAXLEN) {
+ unifi_trace(priv, UDBG3, "unifi_do_associate: adding wmm ie in probe request.\n");
+ if (priv->wext_conf.bss_wmm_capabilities & QOS_CAPABILITY_WMM_UAPSD) {
+ unifi_trace(priv, UDBG3, "unifi_do_associate: adding U-APSD mask (0x%x).\n",
+ priv->wext_conf.wmm_bss_uapsd_mask);
+ wmm_ie[WMM_IE_QOS_INFO_OFFSET] |= priv->wext_conf.wmm_bss_uapsd_mask;
+ }
+ /* Append the WMM ie at the end of the buffer */
+ append_wmm_ie = 1;
+ /* update the length we will tell the device */
+ ie_request_len = conf->generic_ie_len + WMM_IE_SIZE;
+ }
+ else {
+ unifi_notice(priv, "unifi_do_associate: Not enough room in generic_ie for WMM.\n");
+ /* update the length we will tell the device */
+ ie_request_len = conf->generic_ie_len;
+ }
+ }
+ else {
+ /* update the length we will tell the device */
+ ie_request_len = conf->generic_ie_len;
+ }
+
+ if (ie_request_len) {
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], ie_request_len);
+ if (r != 0) {
+ unifi_error(priv, "unifi_do_associate: failed to allocate ie_request_buf.\n");
+ return -EIO;
+ }
+ ie_request_buf = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ if (conf->generic_ie_len) {
+ memcpy(ie_request_buf, conf->generic_ie, conf->generic_ie_len);
+ }
+ if (append_wmm_ie) {
+ memcpy(ie_request_buf + conf->generic_ie_len, wmm_ie, WMM_IE_SIZE);
+ }
+ }
+
+ memcpy((void*)req->PeerStaAddress.x, (void*)priv->wext_conf.current_bssid, 6);
+
+ req->AssociateFailureTimeout = conf->assoc_failure_timeout;
+ req->CapabilityInformation = (s16)host2unifi_16(conf->capability);
+ /* Convert msecs to beacon periods */
+ if (si->msi.BeaconPeriod > 0) {
+ req->ListenInterval = conf->assoc_listen_interval / si->msi.BeaconPeriod;
+ } else {
+ req->ListenInterval = 1;
+ }
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_ASSOCIATE_REQUEST_ID;
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = ie_request_buf;
+ data_ptrs.d[0].data_length = ie_request_len;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ /*
+ * Calculate a suitable transport timeout.
+ * Use the operation timeout plus 50%.
+ */
+ timeout = conf->assoc_failure_timeout + conf->assoc_failure_timeout/2;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send ASSOCIATE request, error %d\n", r);
+ return r;
+ }
+
+ rc = pcli->reply_signal->u.MlmeAssociateConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "ASSOCIATE request was rejected with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ return -EIO;
+ }
+
+ priv->wext_conf.flag_associated = 1;
+
+ /*
+ * Need to send IW events for assoc request IE and assoc response IE
+ * and then a SIOCGIWAP event.
+ */
+ ie_confirm_len = pcli->reply_signal->u.MlmeAssociateConfirm.InformationElements.DataLength;
+ if ((ie_confirm_len > 0) && (ie_confirm_len < IE_VECTOR_MAXLEN)) {
+ memcpy(ie_confirm_vector, pcli->reply_bulkdata[0]->ptr, ie_confirm_len);
+ wext_send_assoc_event(priv, priv->wext_conf.current_bssid,
+ conf->generic_ie, conf->generic_ie_len,
+ ie_confirm_vector, ie_confirm_len,
+ NULL, 0);
+
+ /* Need to get information about QOS from the assoc response */
+ r = get_wmm_bss_capabilities(priv, ie_confirm_vector, ie_confirm_len,
+ &priv->wext_conf.bss_wmm_capabilities);
+ if (r == 1) {
+ /* Set any Traffic Streams if nessesary. */
+ priv->sta_wmm_capabilities = priv->wext_conf.bss_wmm_capabilities;
+ set_wmm_traffic_streams(priv);
+ } else {
+ priv->sta_wmm_capabilities = 0;
+ }
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_do_associate() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_set_powermode
+ *
+ * Send a MLME-POWERMGT request using the values in the wext_conf
+ * struct.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_set_powermode(unifi_priv_t *priv)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_POWERMGT_REQUEST *req = &signal.u.MlmePowermgtRequest;
+ struct wext_config *conf= &priv->wext_conf;
+ int timeout = 1000;
+ int r, rc;
+ ul_client_t *pcli = priv->wext_client;
+
+ func_enter();
+
+ unifi_trace(priv, UDBG1, "powermgt: mode=%d\n", conf->power_mode);
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_POWERMGT_REQUEST_ID;
+
+ req->PowerManagementMode = conf->power_mode;
+ req->WakeUp = 0;
+ req->ReceiveDtims = conf->wakeup_for_dtims;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, NULL, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send POWERMGT request, error %d\n", r);
+ return r;
+ }
+
+ rc = pcli->reply_signal->u.MlmePowermgtConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "POWERMGT request was rejected with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ return -EIO;
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_set_powermode() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * _join_ap
+ *
+ * Establish ourself as a member of a given Access Point (AP).
+ * This means doing JOIN, AUTHENTICATE and ASSOCIATE actions.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ * si Pointer to scan_info_t entry for the AP tp join.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+_join_ap(unifi_priv_t *priv, scan_info_t *si)
+{
+ int r;
+
+ func_enter();
+
+ /* Reset the f/w 802.11 state */
+ r = unifi_reset_state(priv, priv->netdev->dev_addr, 0);
+ if (r) {
+ unifi_notice(priv, "Failed to reset device\n");
+ func_exit();
+ return r;
+ }
+
+ r = unifi_do_join(priv, si);
+ if (r) {
+ unifi_notice(priv, "Failed to join wireless network\n");
+ func_exit();
+ return r;
+ }
+
+ /* Set power-saving mode if requested, the previous mlme-reset clears it. */
+ if ((priv->wext_conf.capability & SIG_CAP_IBSS) == 0) {
+ if (priv->wext_conf.power_mode) {
+ r = unifi_set_powermode(priv);
+ if (r) {
+ unifi_notice(priv, "Failed to set powersave mode\n");
+ func_exit();
+ return r;
+ }
+ }
+ }
+
+ /*
+ * F/W needs to have a dummy protection set before it can transmit
+ * the WPA opening sequences.
+ */
+#if WIRELESS_EXT > 17
+ if ((priv->wext_conf.wpa_version == IW_AUTH_WPA_VERSION_WPA) ||
+ (priv->wext_conf.wpa_version == IW_AUTH_WPA_VERSION_WPA2))
+ {
+ r = mlme_set_protection(priv, priv->wext_conf.current_bssid,
+ CSR_PT_NONE, CSR_PAIRWISE);
+ if (r) {
+ unifi_notice(priv, "Failed to set dummy WPA protection (pairwise key)\n");
+ func_exit();
+ return r;
+ }
+
+ r = mlme_set_protection(priv, priv->wext_conf.current_bssid,
+ CSR_PT_NONE, CSR_GROUP);
+ if (r) {
+ unifi_notice(priv, "Failed to set dummy WPA protection (group key)\n");
+ func_exit();
+ return r;
+ }
+ }
+#endif
+
+ /* Procedure for joining an IBSS stops here */
+ if ((priv->wext_conf.capability & SIG_CAP_IBSS) != 0) {
+ func_exit();
+ return 0;
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* This is for Infrastructure networks */
+
+ /* send AUTHENTICATE */
+ r = unifi_do_authenticate(priv);
+ if (r) {
+ unifi_notice(priv, "Failed to authenticate with wireless network\n");
+ func_exit();
+ return r;
+ }
+
+ /* send ASSOCIATE */
+ r = unifi_do_associate(priv, si);
+ if (r) {
+ unifi_notice(priv, "Failed to associate with wireless network\n");
+ func_exit();
+ return r;
+ }
+
+ func_exit();
+ return 0;
+} /* _join_ap() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_join_bss
+ * unifi_join_ap
+ *
+ * These two functions do the same task, but use alternate ways
+ * to specify the AP.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ * si Pointer to scan_info_t entry for the AP tp join.
+ * bss MAC address of AP to join. This must exist in the
+ * current set of scan results.
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_join_ap(unifi_priv_t *priv, scan_info_t *si)
+{
+ int r;
+ char ssid[UNIFI_MAX_SSID_LEN];
+ char *elem;
+
+ /* Find the SSID field */
+ memset(ssid, 0, UNIFI_MAX_SSID_LEN);
+ elem = (char *)unifi_find_info_element(IE_SSID_ID,
+ si->info_elems,
+ si->info_elem_length);
+ if (elem) {
+ int elen;
+ elen = elem[1];
+ if (elen > UNIFI_MAX_SSID_LEN) {
+ elen = UNIFI_MAX_SSID_LEN;
+ }
+ strncpy(ssid, elem + 2, elen);
+ } else {
+ strncpy(ssid, "<unknown>", UNIFI_MAX_SSID_LEN);
+ }
+
+ /*
+ * We have to search for WMM ie at this point. We are going to use
+ * this information later, when we set the association request.
+ * There is no way to know if our AP supports QOS other than parsing
+ * the IEs we have got from the beacons and probe responses.
+ */
+ r = get_wmm_bss_capabilities(priv, si->info_elems, si->info_elem_length,
+ &priv->wext_conf.bss_wmm_capabilities);
+ if (r == 1) {
+ /* Don't expect an association response in Ad-Hoc. */
+ if (si->msi.BssType == CSR_INDEPENDENT) {
+ unifi_trace(priv, UDBG1, "unifi_join_ap: IBSS supports WMM\n");
+ priv->sta_wmm_capabilities = priv->wext_conf.bss_wmm_capabilities;
+ }
+ } else {
+ priv->sta_wmm_capabilities = 0;
+ }
+
+ unifi_trace(priv, UDBG1, "joining ssid=\"%s\"\n", ssid);
+ r = _join_ap(priv, si);
+
+ if (r) {
+ unifi_notice(priv, "Failed to join \"%s\"\n", ssid);
+ } else {
+ /* Success. Remember the SSID and report it in the log. */
+ strncpy(priv->wext_conf.current_ssid, ssid, UNIFI_MAX_SSID_LEN);
+
+ if ((priv->wext_conf.capability & SIG_CAP_IBSS) != 0) {
+ unifi_notice(priv, "Joined ad-hoc network \"%s\"\n", priv->wext_conf.current_ssid);
+ } else {
+ unifi_notice(priv, "Associated with \"%s\"\n", priv->wext_conf.current_ssid);
+ }
+ }
+
+ return r;
+} /* unifi_join_ap() */
+
+
+int
+unifi_join_bss(unifi_priv_t *priv, unsigned char *macaddr)
+{
+ scan_info_t *psi;
+ int i;
+ char *elem;
+ int desired_ssid_len = strlen(priv->wext_conf.desired_ssid);
+
+ func_enter();
+
+ /* Look for bss in scan list */
+ psi = NULL;
+
+ for (i = 0; 1; i++) {
+ psi = unifi_get_scan_report(priv, i);
+ if (psi == NULL) {
+ unifi_trace(priv, UDBG2, "Exhausted Scan Results.\n");
+ break;
+ }
+ /* Check if the requested BSSID matches the scan result. */
+ if (memcmp(macaddr, psi->msi.Bssid.x, ETH_ALEN) == 0) {
+ /* The requested BSSID must belong to the last set SSID. */
+ if (desired_ssid_len > 0) {
+ /* Get the SSID from the san result.*/
+ elem = (char *)unifi_find_info_element(IE_SSID_ID,
+ psi->info_elems,
+ psi->info_elem_length);
+ if (elem != NULL) {
+ int elen;
+ elen = elem[1];
+ if (elen > UNIFI_MAX_SSID_LEN) {
+ elen = UNIFI_MAX_SSID_LEN;
+ }
+ /* The lengths must be equal .. */
+ if (elen == desired_ssid_len) {
+ /* .. and the SSIDs. */
+ if (memcmp(priv->wext_conf.desired_ssid, elem + 2, elen) == 0) {
+ break;
+ }
+ }
+ } else {
+ unifi_notice(priv, "Scan Result with no SSID IE.\n");
+ }
+ }
+ else {
+ /* found it */
+ unifi_trace(priv, UDBG2, "Desired SSID empty, BSSID match..\n");
+ break;
+ }
+ }
+ }
+
+ if (psi == NULL) {
+ unifi_error(priv, "Requested AP BSS not found in scan list\n");
+ return -EINVAL;
+ }
+
+ func_exit();
+
+ return unifi_join_ap(priv, psi);
+} /* unifi_join_bss() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_autojoin
+ *
+ * This function implements a very basic Station Management Entity (SME).
+ *
+ * Perform all the operations needed to join a WiFi network.
+ * This involves:
+ * - a scan to detect networks (adhoc and AP) available
+ * - MLME-JOIN to join the network or MLME-START to start an adhoc
+ * network
+ * - authenticate and associate
+ *
+ * Arguments:
+ * priv Pointer to driver private struct.
+ *
+ * Returns:
+ * 0 on success, error code on failure
+ *
+ * Notes:
+ * Results of the scan are stored by the driver core in the card
+ * struct. We use unifi_get_scan_report() to retrieve the list.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_autojoin(unifi_priv_t *priv, const char *ssid)
+{
+ struct wext_config *conf;
+ scan_info_t *si;
+ int i, r;
+ int ssid_len = 0;
+ int best_snr;
+ CSR_BSS_TYPE bsstype;
+
+ conf = &priv->wext_conf;
+
+ /*
+ * Scan for networks.
+ */
+ switch (conf->mode) {
+ case IW_MODE_ADHOC: bsstype = CSR_INDEPENDENT; break;
+ case IW_MODE_INFRA: bsstype = CSR_INFRASTRUCTURE; break;
+ default: bsstype = CSR_ANY_BSS; break;
+ }
+
+ LOCK_DRIVER(priv);
+ unifi_trace(priv, UDBG1, "scanning for bsstype %d\n", bsstype);
+ if (ssid) {
+ ssid_len = strlen(ssid);
+ r = unifi_do_scan(priv, UNIFI_SCAN_ACTIVE, bsstype, ssid, ssid_len);
+ } else {
+ /* Wildcard scan */
+ r = unifi_do_scan(priv, UNIFI_SCAN_ACTIVE, bsstype, NULL, 0);
+ }
+ UNLOCK_DRIVER(priv);
+ if (r) {
+ unifi_error(priv, "Scan failed\n");
+ func_exit();
+ return r;
+ }
+
+ /* Drop any existing association */
+ if (priv->wext_conf.flag_associated) {
+ unifi_leave(priv);
+ }
+
+
+ /* If an SSID is given, search scan list for a matching SSID. */
+ /* Otherwise take first found */
+ si = NULL;
+ if (ssid == NULL)
+ {
+ /* No SSID given, just take the first in the list */
+ /* Could look for the strongest here */
+ unifi_trace(priv, UDBG1, "selecting first AP in scan list\n");
+ si = unifi_get_scan_report(priv, 0);
+ }
+ else
+ {
+ unifi_trace(priv, UDBG1, "checking scan list for SSID \"%s\"\n", ssid);
+ best_snr = -1; /* force first result to win */
+ for (i = 0; 1; i++) {
+ scan_info_t *psi;
+ char *elem;
+ int e_len;
+ char *e_ptr;
+
+ psi = unifi_get_scan_report(priv, i);
+ if (!psi) {
+ break;
+ }
+
+ elem = (char *)unifi_find_info_element(IE_SSID_ID,
+ psi->info_elems,
+ psi->info_elem_length);
+ if (!elem) {
+ /* No SSID field in this scan result */
+ continue;
+ }
+
+ e_len = elem[1];
+ e_ptr = elem + 2;
+#if 0
+ /* debugging */
+ if (e_len) {
+ printk(" comparing entry %d: \"%s\"\n", i, e_ptr);
+ } else {
+ printk(" entry %d has zero length SSID\n", i);
+ }
+#endif
+ if ((e_len == ssid_len) && (strncmp(e_ptr, ssid, e_len) == 0))
+ {
+ int snr;
+ /* Found a match, is this the strongest signal? */
+ /* SNR is an unsigned 16-bit value. */
+ snr = (s16)unifi2host_16(psi->msi.Snr);
+ if (snr > best_snr) {
+ si = psi;
+ }
+ }
+ }
+ }
+ /* Didn't find requested network */
+ if (si == NULL)
+ {
+ unifi_trace(priv, UDBG1, "Network not found in scan list\n");
+ /*
+ * If an SSID was given and mode is ADHOC then start an IBSS.
+ */
+ if (ssid_len && (conf->mode == IW_MODE_ADHOC))
+ {
+ r = unifi_do_start(priv, ssid);
+ if (r) {
+ func_exit();
+ return r;
+ }
+ unifi_notice(priv, "Started adhoc network \"%s\"\n", ssid);
+
+ func_exit();
+ return 0;
+ }
+
+ /* Couldn't find a network to join, report failure. */
+ if (ssid_len == 0) {
+ unifi_notice(priv, "Didn't find a network to join\n");
+ } else {
+ unifi_notice(priv, "Network \"%s\" not found\n", ssid);
+ }
+
+ func_exit();
+ return -ENETUNREACH;
+ }
+
+ /* send JOIN with info for desired network */
+ r = unifi_join_ap(priv, si);
+ if (r) {
+ /* Clean up if JOIN fails */
+ memset(priv->wext_conf.current_ssid, 0, UNIFI_MAX_SSID_LEN);
+ memset((void*)priv->wext_conf.current_bssid, 0, ETH_ALEN);
+ priv->wext_conf.capability = 0;
+ priv->wext_conf.flag_associated = 0;
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_autojoin() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_leave
+ *
+ * Disassociate from a BSS.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * 0 on success or error code.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_leave(unifi_priv_t *priv)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_DISASSOCIATE_REQUEST *req = &signal.u.MlmeDisassociateRequest;
+ bulk_data_param_t data_ptrs;
+ struct wext_config *conf= &priv->wext_conf;
+ int timeout = 5000;
+ int r;
+ ul_client_t *pcli = priv->wext_client;
+ unsigned char *ie_request_buf = NULL;
+ unsigned int ie_request_len = 0;
+
+ func_enter();
+
+ unifi_notice(priv, "Leaving wireless network \"%s\"\n", priv->wext_conf.current_ssid);
+
+ /* Configure the deep sleep signaling */
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_ENABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+
+ memcpy((void*)req->PeerStaAddress.x,
+ (void*)priv->wext_conf.current_bssid, ETH_ALEN);
+ req->ReasonCode = 1; /* UnspecifiedReason */
+
+#if 0
+ printk("disass: addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+ req.PeerStaAddress.x[0], req.PeerStaAddress.x[1], req.PeerStaAddress.x[2],
+ req.PeerStaAddress.x[3], req.PeerStaAddress.x[4], req.PeerStaAddress.x[5]);
+#endif
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_DISASSOCIATE_REQUEST_ID;
+
+ if (conf->generic_ie_len) {
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], conf->generic_ie_len);
+ if (r != 0) {
+ unifi_error(priv, "unifi_leave: failed to allocate ie_request_buf.\n");
+ return -EIO;
+ }
+ ie_request_buf = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ memcpy(ie_request_buf, conf->generic_ie, conf->generic_ie_len);
+ ie_request_len = conf->generic_ie_len;
+ }
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = ie_request_buf;
+ data_ptrs.d[0].data_length = ie_request_len;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send DISASSOCIATE request, error %d\n", r);
+ return r;
+ }
+
+ r = pcli->reply_signal->u.MlmeDisassociateConfirm.ResultCode;
+ if (r) {
+ unifi_notice(priv, "DISASSOCIATE request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ /* Not fatal, we still want to clean up as if it succeeded. */
+ }
+
+ /*
+ * Send wireless-extension event up to userland to announce
+ * connection lost to a BSS.
+ */
+ wext_send_disassoc_event(priv);
+
+ /*
+ * Invalidate the generic_ie information.
+ * When the wpa_supplicant re-configures us, it will set the new IEs.
+ */
+ conf->generic_ie_len = 0;
+
+ memset(priv->wext_conf.current_ssid, 0, UNIFI_MAX_SSID_LEN);
+ memset((void*)priv->wext_conf.current_bssid, 0, ETH_ALEN);
+ priv->wext_conf.capability = 0;
+ priv->wext_conf.flag_associated = 0;
+
+ func_exit();
+
+ return 0;
+} /* unifi_leave() */
+
+
+
+/*
+ * -------------------------------------------------------------------------
+ * unifi_reset_state
+ *
+ * Ensure that a MAC address has been set.
+ * Send the MLME-RESET signal.
+ * This must be called at least once before starting to do any
+ * network activities (e.g. scan, join etc).
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * macaddr Pointer to chip MAC address.
+ * If this is FF:FF:FF:FF:FF:FF it will be replaced
+ * with the MAC address from the chip.
+ * set_default_mib 1 if the f/w must reset the MIB to the default values
+ * 0 otherwise
+ *
+ * Returns:
+ * 0 on success, an error code otherwise.
+ * -------------------------------------------------------------------------
+ */
+int
+unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr,
+ unsigned char set_default_mib)
+{
+ ul_client_t *pcli = priv->wext_client;
+ int r;
+
+ func_enter();
+
+ r = unifi_mlme_reset(priv, pcli, macaddr, set_default_mib);
+ if (r) {
+ unifi_notice(priv, "MLME-RESET request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ }
+
+ TIME_MARK("MLME-RESET sent");
+
+ /* The reset clears any 802.11 association. */
+ priv->wext_conf.flag_associated = 0;
+ /*
+ * The counter for the multicast addresses list needs
+ * to be clear after reset, since the f/w clears the list.
+ */
+ priv->mc_list_count_stored = 0;
+
+ func_exit();
+ return r;
+} /* unifi_reset_state() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Utility functions.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_find_info_element
+ *
+ * Search an Information Element vector for a particular id number.
+ *
+ * Arguments:
+ * id IE number to search for.
+ * info Pointer to the IE vector to search.
+ * len Length of the IE vector.
+ *
+ * Returns:
+ * Pointer to info element or NULL if not found.
+ *
+ * Notes:
+ * ---------------------------------------------------------------------------
+ */
+const unsigned char *
+unifi_find_info_element(int id, const unsigned char *info, int len)
+{
+ const unsigned char *ie = info;
+
+ while (len > 1)
+ {
+ int e_id, e_len;
+ e_id = ie[0];
+ e_len = ie[1];
+
+ /* Return if we find a match */
+ if (e_id == id)
+ {
+ return ie;
+ }
+
+ len -= (e_len + 2);
+ ie += (e_len + 2);
+ }
+
+ return NULL;
+} /* unifi_find_info_element() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_add_info_element
+ *
+ * Add an Information Element to an IE vector.
+ *
+ * Arguments:
+ * info Pointer to position in the IE vector to write to.
+ * ie_id IE number to add.
+ * ie_data IE number to add.
+ * ie_len Length of the data to add.
+ *
+ * Returns:
+ * Number of bytes written to info
+ *
+ * Notes:
+ * Assumes there is enough space in info for ie_len+2 bytes.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_add_info_element(unsigned char *info,
+ int ie_id,
+ const unsigned char *ie_data, int ie_len)
+{
+ info[0] = ie_id & 0xff;
+ info[1] = ie_len & 0xff;
+
+ memcpy(info + 2, ie_data, ie_len & 0xff);
+
+ return (ie_len & 0xff) + 2;
+} /* unifi_add_info_element() */
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mib.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mib.c
new file mode 100644
index 0000000..52a9b8d
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mib.c
@@ -0,0 +1,682 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: mib.c
+ *
+ * PURPOSE:
+ * This file provides functions to send MLME requests to the UniFi.
+ * It is OS-independent.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+#define MIB_TAG_BOOLEAN 0x01
+#define MIB_TAG_INTEGER 0x02
+#define MIB_TAG_OCTETSTRING 0x04
+#define MIB_TAG_OID 0x06
+#define MIB_TAG_SEQUENCE 0x30
+
+
+#ifndef isdigit
+#define isdigit(_c) (((_c) >= '0') && ((_c) <= '9'))
+#endif
+
+
+/* How much buffer space to use for varbinds */
+#define VARBIND_LENGTH 128
+
+static int MibEncodeOID(const char *oid_str, unsigned char *aData);
+static int MibEncodeVarBindInt(int aInt, unsigned char *aData);
+static int MibEncodeInteger(int aVal, unsigned char *aData);
+static int MibEncodeOctetString(unsigned char *aStr, int aStrLength, unsigned char *aData);
+#if 0
+static int MibEncodeBoolean(unsigned char aVal, unsigned char *aData);
+static int MibDecodeBoolean(unsigned char *aData, uint32 *aVal);
+static int MibDecodeInteger(unsigned char *aData, uint32 *aVal);
+static int MibDecodeOctetString(unsigned char *aData, int aDataLength, unsigned char *aStr);
+#endif
+
+
+
+
+#define dot11MACAddress_oid "1.2.840.10036.2.1.1.1.1"
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_decimal
+ *
+ * Scan a string for digits. Convert the digits (up to a non-digit
+ * delimiter) into a decimal number.
+ *
+ * Arguments:
+ * s String to scan
+ * val Pointer to which to write the result
+ *
+ * Returns:
+ * NUmber of characters used.
+ * ---------------------------------------------------------------------------
+ */
+static int
+read_decimal(const char *s, int *val)
+{
+ const char *p = s;
+ int v = 0;
+
+ /* Convert the number */
+ while (*p && isdigit(*p)) {
+ v = (v * 10) + *p - '0';
+ p++;
+ }
+
+ *val = v;
+
+ return p - s;
+} /* read_int() */
+
+
+/*
+ * ******************************************************************************
+ * MibEncodeOID -
+ *
+ * PARAMETERS
+ * aBindIndex - Index into gVarBinds.
+ * aIndices - Pointer to array of indices for table entry.
+ * aNumIndices - Number of indices in the aIndices array. Must match the
+ * mNumIndices member in gVarBinds entry given by aBindIndex.
+ * buf - Pointer to buffer to encode varbind into.
+ *
+ * RETURNS
+ * Number of bytes written into buffer pointed to by aData.
+ *
+ * REMARKS
+ * This function makes the following assumptions:
+ * 1) The contents field will be no longer than 127 octets when encoded.
+ *
+ */
+static int
+MibEncodeOID(const char *oid_str, unsigned char *buf)
+{
+ int length = 0;
+ unsigned char *data = buf;
+ const char *p;
+ int id, tmp;
+ int i;
+
+ buf[0] = MIB_TAG_OID;
+ data = buf + 2; /* Assuming length will always be 1 octet */
+
+ p = oid_str;
+ i = 0;
+ while (*p)
+ {
+ /* Read integer from string */
+ p += read_decimal(p, &id);
+ if (*p) p++; /* step over separator */
+
+ switch (i)
+ {
+ case 0:
+ *data = 40 * id;
+ length++;
+ break;
+ case 1:
+ *data += id;
+ data++;
+ break;
+ default:
+ tmp = MibEncodeVarBindInt(id, data);
+ length += tmp;
+ data += tmp;
+ break;
+ }
+ i++;
+ }
+
+ buf[1] = (unsigned char)length;
+
+ return 2 + length;
+} /* MibEncodeOID() */
+
+
+
+/*
+ * MibEncodeVarBindInt
+ */
+static int
+MibEncodeVarBindInt(int aInt, unsigned char *aData)
+{
+ int bytesWritten;
+ unsigned char value[4];
+ int i;
+
+ for(bytesWritten = 0; bytesWritten < 4; aInt /= 128)
+ {
+ value[bytesWritten] = (unsigned char)(aInt % 128);
+ ++bytesWritten;
+
+ if(aInt <= 127)
+ {
+ break;
+ }
+ }
+
+ for(i = bytesWritten - 1; i >= 0; --i, ++aData)
+ {
+ *aData = value[i];
+ if(i > 0)
+ {
+ *aData += 0x80;
+ }
+ }
+
+ return bytesWritten;
+} /* MibEncodeVarBindInt() */
+
+
+/*
+ * MibEncodeNull
+ */
+static int
+MibEncodeNull(unsigned char *aData)
+{
+ aData[0] = 5;
+ aData[1] = 0;
+
+ return 2;
+} /* MibEncodeNull() */
+
+
+
+/*
+ * ******************************************************************************
+ * MibEncodeInteger -
+ *
+ * RETURNS
+ * Number of bytes written into buffer pointed to by aData.
+ *
+ */
+static int
+MibEncodeInteger(int aVal, unsigned char *aData)
+{
+ int length = 0;
+ unsigned char valBytes[5] = { 0, 0, 0, 0, 0 };
+ unsigned char *data = aData;
+ int val = aVal;
+ int i;
+
+ *data = MIB_TAG_INTEGER;
+ data += 2; /* Assuming length will always be 1 octet */
+
+ do
+ {
+ if(val == 0)
+ {
+ *data = 0;
+ length = 1;
+ break;
+ }
+
+ while((val != 0) && (length < 4))
+ {
+ valBytes[length] = (val & 0xff);
+ ++length;
+ if((val < -128) || (val > 127))
+ {
+ val >>= 8;
+ }
+ else
+ {
+ /* Ensures we only use the minimum number of contents octets */
+ val = 0;
+ }
+ }
+
+ if((aVal > 0) && (valBytes[length - 1] & 0x80))
+ {
+ valBytes[length] = 0;
+ ++length;
+ }
+
+ for(i = length - 1; i >= 0; --i)
+ {
+ *data = valBytes[i]; ++data;
+ }
+ }
+ while(0);
+
+ aData[1] = (unsigned char)length;
+
+ return 2 + length;
+} /* MibEncodeInteger() */
+
+
+
+/*
+ * ******************************************************************************
+ * MibEncodeOctetString -
+ *
+ * PARAMETERS
+ * aStrLength - Number of bytes pointed to by aStr (<= 255).
+ * aStr - Pointer to an array of bytes to include in the octet string.
+ * aData - Pointer to buffer to encode octet string into.
+ *
+ * RETURNS
+ * Number of bytes written into buffer pointed to by aData.
+ *
+ * REMARKS
+ * This encoding is always primitive.
+ *
+ */
+static int
+MibEncodeOctetString(unsigned char *aStr, int aStrLength, unsigned char *aData)
+{
+ unsigned char *data = aData;
+ unsigned char *inData = aStr;
+ int i;
+
+ *data = MIB_TAG_OCTETSTRING;
+ data += 2; /* Assuming length will always be 1 octet */
+
+ for(i = 0; i < aStrLength; ++i, ++data, ++inData)
+ {
+ *data = *inData;
+ }
+
+ aData[1] = (unsigned char)aStrLength;
+
+ return 2 + aStrLength;
+} /* MibEncodeOctetString() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * MibDecodeInteger
+ *
+ * Decode a varbind from UniFi MLME-GET result into an integer value.
+ *
+ * Arguments:
+ * aData Pointer to varbind.
+ * aVal Pointer to integer for return value.
+ *
+ * Returns:
+ * Size of integer read in bytes (1,2,3,4) or 0 on error.
+ *
+ * Notes:
+ * This function will only decode up to 32-bit integers.
+ * ---------------------------------------------------------------------------
+ */
+static int
+MibDecodeInteger(unsigned char *aData, unsigned int *aVal)
+{
+ unsigned char *data = aData + 2;
+ int nbytes;
+ int i = 0;
+ unsigned int u;
+
+ if(aData[0] != MIB_TAG_INTEGER)
+ {
+ return 0;
+ }
+
+ nbytes = aData[1];
+ if (nbytes > 4)
+ {
+ return 0;
+ }
+
+ if (nbytes == 0)
+ {
+ *aVal = 0;
+ }
+
+ u = (data[0] & 0x80) ? 0xFFFFFFFF : 0;
+
+ for (i = 0; i < nbytes; i++)
+ {
+ u = (u << 8) | data[i];
+ }
+ *aVal = u;
+
+ return nbytes;
+} /* MibDecodeInteger() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * lookup_mib_status
+ *
+ * desc
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static const char *
+lookup_mib_status(int status)
+{
+ const char *str;
+
+ switch (status) {
+ case CSR_MIB_SUCCESSFUL:
+ str = "Success";
+ break;
+
+ case CSR_MIB_INVALID_PARAMETERS:
+ str = "Invalid Parameters";
+ break;
+
+ case CSR_MIB_WRITE_ONLY:
+ str = "Write only";
+ break;
+
+ case CSR_MIB_READ_ONLY:
+ str = "Read only";
+ break;
+
+ default:
+ str = "<unknown>";
+ }
+
+ return str;
+} /* lookup_mib_status() */
+
+
+
+/*
+ * ----------------------------------------------------------------
+ * unifi_get_mib
+ * unifi_set_mib
+ *
+ * This function is called from the driver ioctl method to
+ * handle UNIFI_GET_MIB and UNIFI_SET_MIB.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * varbind Pointer to MIB varbind passed by the user.
+ * maxlen The number of bytes available in varbind
+ * for the return value.
+ *
+ * Returns:
+ * 0 on success,
+ * -ve number: transport error code
+ * +ve number: MIB Status code returned by UniFi:
+ * 1 Invalid Parameters
+ * 2 Write only
+ * 3 Read only
+ * ----------------------------------------------------------------
+ */
+int
+unifi_set_mib(unifi_priv_t *priv, ul_client_t *pcli, unsigned char *varbind)
+{
+ CSR_SIGNAL signal;
+ bulk_data_param_t data_ptrs;
+ int r, status;
+ int timeout = 1000;
+ unsigned char *request_buf = NULL;
+ unsigned int request_len = 0;
+
+ /* Check varbind begins with a SEQUENCE tag */
+ if (varbind[0] != MIB_TAG_SEQUENCE) {
+ return -EINVAL;
+ }
+
+ /* Extract total length */
+ request_len = varbind[1] + 2;
+
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], request_len);
+ if (r != 0) {
+ unifi_error(priv, "unifi_set_mib: failed to allocate request_buf.\n");
+ return -EIO;
+ }
+ request_buf = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ memcpy(request_buf, varbind, request_len);
+
+#if 0
+ printk("ioctl MIB SET varbind (%d):\n", vb_len);
+ dump(varbind, vb_len);
+#endif
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SET_REQUEST_ID;
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = request_buf;
+ data_ptrs.d[0].data_length = request_len;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send SET request, error %d\n", r);
+ return r;
+ }
+
+ status = pcli->reply_signal->u.MlmeSetConfirm.Status;
+ if (status) {
+ unifi_trace(priv, UDBG1, "MIB-SET request was rejected with status 0x%X (%s)\n",
+ status, lookup_mib_status(status));
+ }
+
+ return status;
+} /* unifi_set_mib() */
+
+int
+unifi_get_mib(unifi_priv_t *priv, ul_client_t *pcli, unsigned char *varbind, int maxlen)
+{
+ CSR_SIGNAL signal;
+ bulk_data_param_t data_ptrs;
+ int datalen;
+ int r, status;
+ int timeout = 1000;
+ unsigned char *request_buf = NULL;
+ unsigned int request_len = 0;
+
+ /* Check varbind begins with a SEQUENCE tag */
+ if (varbind[0] != MIB_TAG_SEQUENCE) {
+ return -EINVAL;
+ }
+
+ /* Extract total length */
+ request_len = varbind[1] + 2;
+
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], request_len);
+ if (r != 0) {
+ unifi_error(priv, "unifi_get_mib: failed to allocate request_buf.\n");
+ return -EIO;
+ }
+ request_buf = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ memcpy(request_buf, varbind, request_len);
+
+#if 0
+ printk("ioctl MIB GET varbind:\n");
+ dump(varbind, vb_len);
+#endif
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_GET_REQUEST_ID;
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = request_buf;
+ data_ptrs.d[0].data_length = request_len;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send GET request, error %d\n", r);
+ return r;
+ }
+
+ status = pcli->reply_signal->u.MlmeGetConfirm.Status;
+ if (status) {
+ unifi_trace(priv, UDBG1, "MIB-GET request was rejected with status 0x%X (%s)\n",
+ status, lookup_mib_status(status));
+ return status;
+ }
+
+#if 0
+ printk("ioctl MIB GET result:\n");
+ dump(varbind, varbind[1] + 2);
+#endif
+
+ /* Now retrieve the bulk data */
+ datalen = pcli->reply_bulkdata[0]->length;
+ if (varbind && datalen) {
+ if (datalen > maxlen) {
+ datalen = maxlen;
+ }
+
+ memcpy(varbind, pcli->reply_bulkdata[0]->ptr, datalen);
+ }
+ return 0;
+
+} /* unifi_get_mib() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_set_mib_string
+ * unifi_set_mib_int
+ *
+ * Convenience functions for setting MIB values of OCTETSTRING and
+ * INTEGER types.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * oidstr String describing OID, e.g. "1.2.840.10036.2.1.1.1.1"
+ * value MIB value
+ * val_len Length of string value
+ *
+ * Returns:
+ * 0 on success,
+ * -ve number: transport error code
+ * +ve number: MIB Status code returned by UniFi:
+ * 1 Invalid Parameters
+ * 2 Write only
+ * 3 Read only
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_set_mib_string(unifi_priv_t *priv, ul_client_t *pcli, char *oidstr, unsigned char *value, int val_len)
+{
+ unsigned char varbind[MAX_VARBIND_LENGTH];
+ unsigned char *ptr;
+ int len;
+
+ /* Build a varbind of OID and INTEGER */
+ varbind[0] = MIB_TAG_SEQUENCE;
+ ptr = varbind + 2; /* assumes length will always be one octet */
+
+ len = MibEncodeOID(oidstr, ptr);
+
+ len += MibEncodeOctetString(value, val_len, ptr+len);
+
+ varbind[1] = len;
+
+ return unifi_set_mib(priv, pcli, varbind);
+} /* unifi_set_mib_string() */
+
+int
+unifi_set_mib_int(unifi_priv_t *priv, ul_client_t *pcli, char *oidstr, int value)
+{
+ unsigned char varbind[MAX_VARBIND_LENGTH];
+ unsigned char *ptr;
+ int len;
+
+ /* Build a varbind of OID and INTEGER */
+ varbind[0] = MIB_TAG_SEQUENCE;
+ ptr = varbind + 2; /* assumes length will always be one octet */
+
+ len = MibEncodeOID(oidstr, ptr);
+
+ len += MibEncodeInteger(value, ptr+len);
+
+ varbind[1] = len;
+
+ return unifi_set_mib(priv, pcli, varbind);
+} /* unifi_set_mib_int() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_get_mib_int
+ *
+ * Retrieve and integer MIB value.
+ *
+ * Arguments:
+ * card Pointer to card context struct
+ * oidstr String describing OID, e.g. "1.2.840.10036.2.1.1.1.1"
+ * valuep Pointer to which to write the returned MIB value
+ *
+ * Returns:
+ * 0 on success,
+ * -ve number: transport error code
+ * +ve number: MIB Status code returned by UniFi:
+ * 1 Invalid Parameters
+ * 2 Write only
+ * 3 Read only
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_get_mib_int(unifi_priv_t *priv, ul_client_t *pcli, char *oidstr, int *valuep)
+{
+ unsigned char varbind[MAX_VARBIND_LENGTH];
+ unsigned char *ptr;
+ int vblen;
+ int r;
+
+ /* Build a varbind of OID and INTEGER */
+ varbind[0] = MIB_TAG_SEQUENCE;
+ ptr = varbind + 2; /* assumes length will always be one octet */
+
+ vblen = MibEncodeOID(oidstr, ptr);
+
+ vblen += MibEncodeNull(ptr+vblen);
+
+ varbind[1] = vblen;
+
+ /* Use the ioctl helper fn to execute a MIB GET operation */
+ r = unifi_get_mib(priv, pcli, varbind, MAX_VARBIND_LENGTH);
+ if (r) {
+ return r;
+ }
+
+ /* Retrieve the returned value */
+
+ /* Skip over the varbind SEQUENCE tag and OID */
+ ptr = varbind + 2;
+ ptr += ptr[1] + 2;
+
+ if (ptr[0] != MIB_TAG_INTEGER) {
+ /* unexpected type of return value */
+ unifi_error(priv, "Unexpected type of return value for %s: %d\n",
+ oidstr, ptr[0]);
+ return -EIO;
+ }
+
+ if (MibDecodeInteger(ptr, (unsigned int *)valuep) == 0) {
+ unifi_error(priv, "Malformed return value for %s\n", oidstr);
+ return -EIO;
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_get_mib_int() */
+
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mlme.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mlme.c
new file mode 100644
index 0000000..63dc5fe
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/mlme.c
@@ -0,0 +1,474 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: mlme.c
+ *
+ * PURPOSE:
+ * This file provides functions to send MLME requests to the UniFi.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+
+/* The additional time taken by the UniFi to do a scan per channel */
+#define SCAN_STARTUP_TIME 300 /* in millisecs */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_mlme_wait_for_reply
+ *
+ * Wait for a reply after sending a signal.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * ul_client Pointer to linux client
+ * sig_reply_id ID of the expected reply (defined in sigs.h).
+ * timeout timeout in ms
+ *
+ * Returns:
+ * 0 on success, -ve POSIX code on error.
+ *
+ * Notes:
+ * This function waits for a specific (sig_reply_id) signal from UniFi.
+ * It also match the sequence number of the received (cfm) signal, with
+ * the latest sequence number of the signal (req) we have sent.
+ * These two number match be equal.
+ * Should only be used for waiting xxx.cfm signals and only after
+ * we have sent the matching xxx.req signal to UniFi.
+ * If no response is received within the expected time (timeout), we assume
+ * that the UniFi is busy and return an error.
+ * If the wait is aborted by a kernel signal arriving, we stop waiting.
+ * If a response from UniFi is not what we expected, we discard it and
+ * wait again. This could be a response from an aborted request. If we
+ * see several bad responses we assume we have lost synchronisation with
+ * UniFi.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_mlme_wait_for_reply(unifi_priv_t *priv, ul_client_t *pcli, int sig_reply_id, int timeout)
+{
+ int retries = 0;
+ long r;
+ long t = timeout;
+ unsigned int sent_seq_no;
+
+ /* Convert t in ms to jiffies */
+ t = msecs_to_jiffies(t);
+
+ do {
+ /* Wait for the confirm or timeout. */
+ r = wait_event_interruptible_timeout(pcli->udi_wq,
+ (pcli->wake_up_wq_id) || (priv->io_aborted == 1),
+ t);
+ /* Check for general i/o error */
+ if (priv->io_aborted) {
+ unifi_error(priv, "MLME operation aborted\n");
+ return -EIO;
+ }
+
+ /*
+ * If r=0 the request has timed-out.
+ * If r>0 the request has completed successfully.
+ * If r=-ERESTARTSYS an event (kill signal) has interrupted the wait_event.
+ */
+ if ((r == 0) && (pcli->wake_up_wq_id == 0)) {
+ unifi_error(priv, "mlme_wait: timed-out waiting for %s, after %lu msec.\n",
+ lookup_signal_name(sig_reply_id), jiffies_to_msecs(t));
+ pcli->wake_up_wq_id = 0;
+ return -ETIMEDOUT;
+ } else if (r == -ERESTARTSYS) {
+ unifi_error(priv, "mlme_wait: waiting for %s was aborted.\n", lookup_signal_name(sig_reply_id));
+ pcli->wake_up_wq_id = 0;
+ return -EINTR;
+ } else {
+ /* Get the sequence number of the signal that we previously set. */
+ if (pcli->seq_no != 0) {
+ sent_seq_no = pcli->seq_no - 1;
+ } else {
+ sent_seq_no = 0x0F;
+ }
+
+ unifi_trace(priv, UDBG5, "Received %s, seq: (r:%d, s:%d)\n",
+ lookup_signal_name(pcli->wake_up_wq_id),
+ pcli->wake_seq_no, sent_seq_no);
+
+ /* The two sequence ids must match. */
+ if (pcli->wake_seq_no == sent_seq_no) {
+ /* and the signal ids must match. */
+ if (sig_reply_id == pcli->wake_up_wq_id) {
+ /* Found the expected signal */
+ break;
+ } else {
+ /* This should never happen ... */
+ unifi_error(priv, "mlme_wait: mismatching signal id (%s - exp %s) (seq %d)\n",
+ lookup_signal_name(pcli->wake_up_wq_id),
+ lookup_signal_name(sig_reply_id),
+ pcli->wake_seq_no);
+ pcli->wake_up_wq_id = 0;
+ return -EIO;
+ }
+ }
+ /* Wait for the next signal. */
+ pcli->wake_up_wq_id = 0;
+
+ retries ++;
+ if (retries >= 3) {
+ unifi_error(priv, "mlme_wait: confirm wait retries exhausted (%s - exp %s)\n",
+ lookup_signal_name(pcli->wake_up_wq_id),
+ lookup_signal_name(sig_reply_id));
+ pcli->wake_up_wq_id = 0;
+ return -EIO;
+ }
+ }
+ } while (1);
+
+ pcli->wake_up_wq_id = 0;
+
+ return 0;
+} /* unifi_mlme_wait_for_reply() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_mlme_blocking_request
+ *
+ * Send a MLME request signal to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * pcli Pointer to context of calling process
+ * sig Pointer to the signal to send
+ * data_ptrs Pointer to the bulk data of the signal
+ * timeout The request's timeout.
+ *
+ * Returns:
+ * 0 on success, 802.11 result code on error.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli,
+ CSR_SIGNAL *sig, bulk_data_param_t *data_ptrs,
+ int timeout)
+{
+ int r;
+
+ func_enter();
+
+ if (sig->SignalPrimitiveHeader.SignalId == 0) {
+ unifi_error(priv, "unifi_mlme_blocking_request: Invalid Signal Id (0x%x)\n",
+ sig->SignalPrimitiveHeader.SignalId);
+ return -EINVAL;
+ }
+
+ down(&priv->mlme_blocking_mutex);
+
+ sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
+ sig->SignalPrimitiveHeader.SenderProcessId = pcli->sender_id | pcli->seq_no;
+
+ unifi_trace(priv, UDBG2, "Send client=%d, S:0x%04X, sig 0x%04X %s\n",
+ pcli->client_id,
+ sig->SignalPrimitiveHeader.SenderProcessId,
+ sig->SignalPrimitiveHeader.SignalId,
+ lookup_signal_name(sig->SignalPrimitiveHeader.SignalId));
+ /* Send the signal to UniFi */
+ r = ul_send_signal_unpacked(priv, sig, data_ptrs);
+ if (r) {
+ up(&priv->mlme_blocking_mutex);
+ unifi_error(priv, "Error queueing MLME REQUEST signal\n");
+ return r;
+ }
+
+ unifi_trace(priv, UDBG5, "Send %s, seq = %d\n",
+ lookup_signal_name(sig->SignalPrimitiveHeader.SignalId), pcli->seq_no);
+
+ /*
+ * Advance the sequence number of the last sent signal, only
+ * if the signal has been successfully set.
+ */
+ pcli->seq_no++;
+ if (pcli->seq_no > 0x0F) {
+ pcli->seq_no = 0;
+ }
+
+ r = unifi_mlme_wait_for_reply(priv, pcli, (sig->SignalPrimitiveHeader.SignalId + 1), timeout);
+ up(&priv->mlme_blocking_mutex);
+
+ if (r) {
+ unifi_error(priv, "Error waiting for MLME CONFIRM signal\n");
+ return r;
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_mlme_blocking_request() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_mlme_copy_reply_and_wakeup_client
+ *
+ * Copy the reply signal from UniFi to the client's structure
+ * and wake up the waiting client.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_mlme_copy_reply_and_wakeup_client(ul_client_t *pcli,
+ CSR_SIGNAL *signal, int signal_len,
+ const bulk_data_param_t *bulkdata)
+{
+ int i;
+
+ /* Copy the signal to the reply */
+ memcpy(pcli->reply_signal, signal, signal_len);
+
+ /* Get the sequence number of the signal that woke us up. */
+ pcli->wake_seq_no = pcli->reply_signal->SignalPrimitiveHeader.ReceiverProcessId & 0x0F;
+
+ /* Append any bulk data */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ if (bulkdata->d[i].data_length > 0) {
+ if (bulkdata->d[i].os_data_ptr) {
+ memcpy(pcli->reply_bulkdata[i]->ptr, bulkdata->d[i].os_data_ptr, bulkdata->d[i].data_length);
+ pcli->reply_bulkdata[i]->length = bulkdata->d[i].data_length;
+ } else {
+ pcli->reply_bulkdata[i]->length = 0;
+ }
+ }
+ }
+
+ /* Wake the requesting MLME function. */
+ pcli->wake_up_wq_id = pcli->reply_signal->SignalPrimitiveHeader.SignalId;
+ wake_up_interruptible(&pcli->udi_wq);
+
+} /* unifi_mlme_copy_reply_and_wakeup_client() */
+
+
+int
+unifi_mlme_reset(unifi_priv_t *priv, ul_client_t *pcli,
+ unsigned char *macaddr, unsigned char set_default_mib)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_RESET_REQUEST *req = &signal.u.MlmeResetRequest;
+ int timeout = 1000;
+ int r;
+
+ func_enter();
+
+ /* Set up MLME-RESET request */
+ memcpy(req->StaAddress.x, macaddr, ETH_ALEN);
+ req->SetDefaultMib = set_default_mib;
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_RESET_REQUEST_ID;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, NULL, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send MLME-RESET request, error %d\n", r);
+ return r;
+ }
+
+ r = pcli->reply_signal->u.MlmeResetConfirm.ResultCode;
+ if (r) {
+ unifi_notice(priv, "MLME-RESET request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ }
+
+ return r;
+} /* unifi_mlme_reset() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_abort_mlme
+ *
+ * Abort any MLME operation in progress.
+ * This is used in the error recovery mechanism.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * 0 on success.
+ * ---------------------------------------------------------------------------
+ */
+int
+unifi_abort_mlme(unifi_priv_t *priv)
+{
+ ul_client_t *ul_cli;
+
+ /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */
+ priv->io_aborted = 1;
+ ul_cli = priv->netdev_client;
+ wake_up_interruptible(&ul_cli->udi_wq);
+
+ ul_cli = priv->wext_client;
+ wake_up_interruptible(&ul_cli->udi_wq);
+
+ ul_cli = priv->multicast_client;
+ wake_up_interruptible(&ul_cli->udi_wq);
+
+ return 0;
+} /* unifi_abort_mlme() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * Human-readable decoding of Reason and Result codes.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+struct mlme_code {
+ const char *name;
+ int id;
+};
+
+static const struct mlme_code Result_codes[] = {
+ { "Success", 0x0000 },
+ { "Unspecified Failure", 0x0001 },
+ /* (Reserved) 0x0002 - 0x0009 */
+ { "Refused Capabilities Mismatch", 0x000A },
+ /* (Reserved) 0x000B */
+ { "Refused External Reason", 0x000C },
+ /* (Reserved) 0x000D - 0x0010 */
+ { "Refused AP Out Of Memory", 0x0011 },
+ { "Refused Basic Rates Mismatch", 0x0012 },
+ /* (Reserved) 0x0013 - 0x001F */
+ { "Failure", 0x0020 },
+ /* (Reserved) 0x0021 - 0x0024 */
+ { "Refused Reason Unspecified", 0x0025 },
+ { "Invalid Parameters", 0x0026 },
+ { "Rejected With Suggested Changes", 0x0027 },
+ /* (Reserved) 0x0028 - 0x002E */
+ { "Rejected For Delay Period", 0x002F },
+ { "Not Allowed", 0x0030 },
+ { "Not Present", 0x0031 },
+ { "Not QSTA", 0x0032 },
+ /* (Reserved) 0x0033 - 0x7FFF */
+ { "Timeout", 0x8000 },
+ { "Too Many Simultaneous Requests", 0x8001 },
+ { "BSS Already Started Or Joined", 0x8002 },
+ { "Not Supported", 0x8003 },
+ { "Transmission Failure", 0x8004 },
+ { "Refused Not Authenticated", 0x8005 },
+ { "Reset Required Before Start", 0x8006 },
+ { "LM Info Unavailable", 0x8007 },
+ { NULL, -1 }
+};
+
+static const struct mlme_code Reason_codes[] = {
+ /* (Reserved) 0x0000 */
+ { "Unspecified Reason", 0x0001 },
+ { "Authentication Not Valid", 0x0002 },
+ { "Deauthenticated Leave BSS", 0x0003 },
+ { "Disassociated Inactivity", 0x0004 },
+ { "AP Overload", 0x0005 },
+ { "Class2 Frame Error", 0x0006 },
+ { "Class3 Frame Error", 0x0007 },
+ { "Disassociated Leave BSS", 0x0008 },
+ { "Association Not Authenticated", 0x0009 },
+ { "Disassociated Power Capability", 0x000A },
+ { "Disassociated Supported Channels", 0x000B },
+ /* (Reserved) 0x000C */
+ { "Invalid Information Element", 0x000D },
+ { "Michael MIC Failure", 0x000E },
+ { "Fourway Handshake Timeout", 0x000F },
+ { "Group Key Update Timeout", 0x0010 },
+ { "Handshake Element Different", 0x0011 },
+ { "Invalid Group Cipher", 0x0012 },
+ { "Invalid Pairwise Cipher", 0x0013 },
+ { "Invalid AKMP", 0x0014 },
+ { "Unsupported RSN IE Version", 0x0015 },
+ { "Invalid RSN IE Capabilities", 0x0016 },
+ { "Dot1X Auth Failed", 0x0017 },
+ { "Cipher Rejected By Policy", 0x0018 },
+ /* (Reserved) 0x0019 - 0x001F */
+ { "QoS Unspecified Reason", 0x0020 },
+ { "QoS Insufficient Bandwidth", 0x0021 },
+ { "QoS Excessive Not Ack", 0x0022 },
+ { "QoS TXOP Limit Exceeded", 0x0023 },
+ { "QSTA Leaving", 0x0024 },
+ { "End TS, End DLS, End BA", 0x0025 },
+ { "Unknown TS, Unknown DLS, Unknown BA", 0x0026 },
+ { "Timeout", 0x0027 },
+ /* (Reserved) 0x0028 - 0x002C */
+ { "STAKey Mismatch", 0x002D },
+ { NULL, -1 }
+};
+
+
+static const char *
+lookup_something(const struct mlme_code *n, int id)
+{
+ for (; n->name; n++) {
+ if (n->id == id) {
+ return n->name;
+ }
+ }
+
+ /* not found */
+ return NULL;
+} /* lookup_something() */
+
+
+const char *
+lookup_result_code(int result)
+{
+ static char fallback[16];
+ const char *str;
+
+ str = lookup_something(Result_codes, result);
+
+ if (str == NULL) {
+ snprintf(fallback, 16, "%d", result);
+ str = fallback;
+ }
+
+ return str;
+} /* lookup_result_code() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * lookup_reason
+ *
+ * Return a description string for a WiFi MLME ReasonCode.
+ *
+ * Arguments:
+ * reason The ReasonCode to interpret.
+ *
+ * Returns:
+ * Pointer to description string.
+ * ---------------------------------------------------------------------------
+ */
+const char *
+lookup_reason_code(int reason)
+{
+ static char fallback[16];
+ const char *str;
+
+ str = lookup_something(Reason_codes, reason);
+
+ if (str == NULL) {
+ snprintf(fallback, 16, "%d", reason);
+ str = fallback;
+ }
+
+ return str;
+} /* lookup_reason_code() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/scan.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/scan.c
new file mode 100644
index 0000000..6704e0b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/scan.c
@@ -0,0 +1,462 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: scan.c
+ *
+ * PURPOSE:
+ * Handle scans.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+
+static int aggregate_info_elements(const unsigned char *old_ie_ptr,
+ int old_ie_len,
+ const unsigned char *new_ie_ptr,
+ int new_ie_len,
+ unsigned char *iebuf, int maxlen);
+
+#ifdef DEBUG_AGGREGATE
+static void decode_info_elements(const unsigned char *info, int infolen);
+#endif /* DEBUG_AGGREGATE */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_get_scan_report
+ *
+ * Access function to retrieve the details of one station found
+ * in the last scan.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ * index The index of the scan data to retrieve.
+ *
+ * Returns:
+ * Pointer to a scan info struct, or
+ * NULL if the entry for <index> is empty.
+ *
+ * Notes:
+ * This is typically called repeatedly with incrementing values index,
+ * starting at zero, until it returns NULL.
+ * ---------------------------------------------------------------------------
+ */
+scan_info_t *
+unifi_get_scan_report(unifi_priv_t *priv, int index)
+{
+ if ((index >= 0) && (index < priv->wext_conf.num_scan_info)) {
+ return &(priv->wext_conf.scan_list[index]);
+ }
+
+ return NULL;
+} /* unifi_get_scan_report() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_clear_scan_table
+ *
+ * Called from mlme_scan_request when the scan should scrap the old table.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_clear_scan_table(unifi_priv_t *priv)
+{
+ int i;
+
+ for (i = 0; i < UNIFI_MAX_SCANS; i++)
+ {
+ scan_info_t *si;
+
+ si = &priv->wext_conf.scan_list[i];
+
+ if (si->info_elems) {
+ unifi_free(priv, si->info_elems);
+ }
+ si->info_elem_length = 0;
+ si->info_elems = NULL;
+ }
+
+ priv->wext_conf.num_scan_info = 0;
+} /* unifi_clear_scan_table() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_scan_indication_handler
+ *
+ * Handle a MLME_SCAN_INDICATION from UniFi.
+ * Adds the scan results to the scan list.
+ * Any existing entry with the same MAC address is replaced, however any
+ * InformationElements in the old entry that are not present in the new
+ * are retained.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ * msg Pointer to the MLME_SCAN_INDICATION message.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * The entries in the scan list consist of the MLME_SCAN_INDICATION struct
+ * with the InformationElements appended. The length of the I-E is given
+ * by the DataRef.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_scan_indication_handler(unifi_priv_t *priv,
+ const CSR_MLME_SCAN_INDICATION *msg,
+ const unsigned char *extra,
+ unsigned int len)
+{
+ int i;
+ unsigned char iebuf[2048];
+ const unsigned char *agg_ie_ptr;
+ int agg_ie_len;
+ const unsigned char *new_ie_ptr;
+ int new_ie_len;
+
+ /* Point to the bulk data containing Info Elems for the new scan */
+ new_ie_ptr = extra;
+ new_ie_len = len;
+
+ /* Look for any matching entry already on the list. */
+ for (i = 0; i < priv->wext_conf.num_scan_info; i++)
+ {
+ scan_info_t *tmp;
+ tmp = &priv->wext_conf.scan_list[i];
+#ifdef DEBUG_AGGREGATE
+ printk("Checking MAC %02X:%02X:%02X:%02X:%02X:%02X\n",
+ tmp->msi.Bssid.x[0], tmp->msi.Bssid.x[1], tmp->msi.Bssid.x[2],
+ tmp->msi.Bssid.x[3], tmp->msi.Bssid.x[4], tmp->msi.Bssid.x[5]);
+#endif /* DEBUG_AGGREGATE */
+ if (memcmp((void*)tmp->msi.Bssid.x, (void*)msg->Bssid.x, sizeof(CSR_MACADDRESS)) == 0)
+ {
+#ifdef DEBUG_AGGREGATE
+ printk(" match!!\n");
+#endif /* DEBUG_AGGREGATE */
+ break;
+ }
+ }
+
+ /*
+ * 'i' either the index of a matching entry in the list,
+ * or the index of the next free entry at the end of the list.
+ */
+ if (i < UNIFI_MAX_SCANS) {
+ scan_info_t *si;
+
+ si = &priv->wext_conf.scan_list[i];
+ memcpy((void*)&si->msi, (void*)msg, sizeof(*msg));
+
+ /* Fallback to the new info */
+ agg_ie_ptr = new_ie_ptr;
+ agg_ie_len = new_ie_len;
+
+ /* If there was old info, combine it with the new */
+ if (si->info_elem_length > 0) {
+ const unsigned char *old_ie_ptr;
+ int old_ie_len;
+
+ /* Build an aggregate list of IEs */
+ old_ie_ptr = si->info_elems;
+ old_ie_len = si->info_elem_length;
+
+ agg_ie_len = aggregate_info_elements(old_ie_ptr, old_ie_len,
+ new_ie_ptr, new_ie_len,
+ iebuf, sizeof(iebuf));
+ agg_ie_ptr = iebuf;
+
+ /* Free old IE */
+ unifi_free(priv, si->info_elems);
+ si->info_elems = NULL;
+ si->info_elem_length = 0;
+ }
+
+ /* Allocate space for the new IE and copy it */
+ if (agg_ie_len > 0) {
+ si->info_elems = (unsigned char *)
+ unifi_malloc(priv, agg_ie_len);
+ if (si->info_elems) {
+ memcpy(si->info_elems, agg_ie_ptr, agg_ie_len);
+ si->info_elem_length = agg_ie_len;
+ }
+ }
+
+ /* If this is a new entry, increment the count */
+ if (i == priv->wext_conf.num_scan_info) {
+ priv->wext_conf.num_scan_info++;
+ }
+ }
+
+} /* unifi_scan_indication_handler() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * aggregate_info_elements
+ *
+ * Combine the Information Element vector from two scan reports for the
+ * same station. The new report supercedes the old report, but any
+ * elements present in the old report that are not overwritten are
+ * retained.
+ *
+ * Arguments:
+ * old_ie_ptr, old_ie_len
+ * Pointer to and length of info elements of older scan
+ * new_ie_ptr, new_ie_len
+ * Pointer to and length of info elements of newer scan
+ * iebuf, maxlen
+ * Pointer to buffer for the new aggregated info elements.
+ *
+ * Returns:
+ * New length of aggregate info element vector.
+ *
+ * Notes:
+ * This code assumes that the Info Elems are in order of increasing
+ * ID number.
+ *
+ * !!!!!
+ * There are some special conditions to watch out for:
+ * - Some vendor-specific ids might legitimately occur more than once,
+ * e.g 221 WPA. We ignore this fact for now, but may need to handle
+ * those IEs differently in the future.
+ * - any wildcard SSIDs (i.e. zero-length, also called broadcast SSID)
+ * should be over-written by a non-wildcard SSID if present.
+ * ---------------------------------------------------------------------------
+ */
+static int
+aggregate_info_elements(const unsigned char *old_ie_ptr, int old_ie_len,
+ const unsigned char *new_ie_ptr, int new_ie_len,
+ unsigned char *iebuf, int maxlen)
+{
+ unsigned char *agg_ie_ptr;
+ int id;
+ const unsigned char *iptr;
+ const unsigned char *old_ssid_ie_ptr;
+ const unsigned char *tmp_old_ie_ptr;
+ const unsigned char *tmp_new_ie_ptr;
+ int tmp_old_ie_len, tmp_new_ie_len, agg_ie_len, agg_ssid_ie_len, old_ssid_ie_len;
+
+
+#ifdef DEBUG_AGGREGATE
+ printk("Agg: old, len=%d\n", old_ie_len);
+ decode_info_elements(old_ie_ptr, old_ie_len);
+
+ printk("Agg: new, len=%d\n", new_ie_len);
+ decode_info_elements(new_ie_ptr, new_ie_len);
+#endif /* DEBUG_AGGREGATE */
+
+ /* Pointer to the aggregation buffer */
+ agg_ie_ptr = iebuf;
+ /* Pointer to the old buffer */
+ tmp_old_ie_ptr = old_ie_ptr;
+ /* Pointer to the new buffer */
+ tmp_new_ie_ptr = new_ie_ptr;
+ /* length of old buffer */
+ tmp_old_ie_len = old_ie_len;
+ /* length of new buffer */
+ tmp_new_ie_len = new_ie_len;
+
+ /* length of aggregation buffer */
+ agg_ie_len = 0;
+ /* length of ssid ie in aggregation buffer */
+ agg_ssid_ie_len = 0;
+
+ /* We assume that the SSID is the first IE */
+ old_ssid_ie_ptr = unifi_find_info_element(0, old_ie_ptr, old_ie_len);
+ if (old_ssid_ie_ptr) {
+ old_ssid_ie_len = old_ssid_ie_ptr[1] + 2;
+ } else {
+ old_ssid_ie_len = 0;
+ }
+
+ /*
+ * update the temp pointer to the old buffer
+ * to point to IEs after the SSID IE
+ */
+ tmp_old_ie_ptr += old_ssid_ie_len;
+
+ /*
+ * Handle SSID (ID 0) specially.
+ *
+ * An SSID with non-zero length in new IE is always taken.
+ * An SSID with non-zero length in old IE beats zero-length in new IE.
+ */
+ iptr = unifi_find_info_element(0, new_ie_ptr, new_ie_len);
+ if (iptr) {
+ /*
+ * There is an SSID in the new IE. Take it, but if it has zero length
+ * check the old IE for a SSID with non-zero length.
+ */
+ if (iptr[1] == 0) {
+ /*
+ * This is a zero-length SSID, see if there is a better
+ * SSID in the old IE.
+ */
+ if (old_ssid_ie_ptr && (old_ssid_ie_ptr[1] > 0)) {
+ iptr = old_ssid_ie_ptr;
+ }
+ }
+
+ /*
+ * update the temp pointer to the new buffer
+ * to point to IEs after the SSID IE
+ */
+ tmp_new_ie_ptr += iptr[1] + 2;
+ tmp_new_ie_len -= iptr[1] + 2;
+ } else {
+ /* No SSID in the new IE, fall back to the value in old IE. */
+ iptr = old_ssid_ie_ptr;
+ }
+ if (iptr) {
+ /* Copy the info elem to the aggregate buffer */
+ int ilen = iptr[1] + 2;
+ memcpy(agg_ie_ptr, iptr, ilen);
+ /* update the aggregation pointer to point after the SSID IE */
+ agg_ie_ptr += ilen;
+ /* store the size of SSID IE in the aggregation buffer*/
+ agg_ssid_ie_len = ilen;
+ }
+
+ /* Copy the old info elem to the aggregate buffer */
+ if (maxlen > old_ie_len) {
+ memcpy(agg_ie_ptr, tmp_old_ie_ptr, old_ie_len - old_ssid_ie_len);
+ agg_ie_len = old_ie_len - old_ssid_ie_len;
+ } else {
+ /* We do not have enough space, copy as much as we can */
+ memcpy(agg_ie_ptr, tmp_old_ie_ptr, maxlen - old_ssid_ie_len);
+ return maxlen;
+ }
+
+ /*
+ * Parse new ie buffer and search for a matching ie in the aggregation buffer
+ */
+ while (tmp_new_ie_len > 0)
+ {
+ const unsigned char *tmp;
+ int ilen;
+ int fiematch = 0;
+ int tmp_agg_ie_len = agg_ie_len;
+ unsigned char* tmp_agg_ie_ptr = agg_ie_ptr;
+
+ /* get the IE id and ID length that we will search for */
+ id = (int)(*tmp_new_ie_ptr);
+ ilen = tmp_new_ie_ptr[1] + 2;
+
+ /* Search for an exact copy of this IE in the aggregation buffer. */
+ while (tmp_agg_ie_len > 0)
+ {
+ tmp = unifi_find_info_element(id, tmp_agg_ie_ptr, tmp_agg_ie_len);
+ /* if the id not not exist we just want to get out of while loop */
+ if (tmp) {
+ /* match the length and the data */
+ if ((tmp[1] == tmp_new_ie_ptr[1]) &&
+ (memcmp(tmp+2, tmp_new_ie_ptr+2, tmp[1]) == 0))
+ {
+ fiematch = 1;
+ tmp_agg_ie_len = 0;
+ }
+
+ /* if they match we just want to get out of while loop */
+ if (!fiematch) {
+ /* advance to the next IE in aggregation buffer */
+ tmp_agg_ie_len -= (tmp - tmp_agg_ie_ptr) + tmp[1] + 2;
+ tmp_agg_ie_ptr = (unsigned char*)tmp + (tmp[1] + 2);
+ }
+ } else {
+ tmp_agg_ie_len = 0;
+ }
+ }
+
+ /* If we have *not* found a match (new IE is unique) we store the new IE */
+ if (!fiematch) {
+ /* check first if we have enough space in aggr buffer */
+ if (maxlen >= agg_ie_len + agg_ssid_ie_len + ilen)
+ {
+ memcpy(agg_ie_ptr+agg_ie_len, tmp_new_ie_ptr, ilen);
+ agg_ie_len += ilen;
+ } else {
+ return agg_ie_len + agg_ssid_ie_len;
+ }
+ }
+
+ /* advance to the next IE in new buffer */
+ tmp_new_ie_ptr += ilen;
+ tmp_new_ie_len -= ilen;
+ }
+
+#ifdef DEBUG_AGGREGATE
+ printk("Agg: agg, len=%d\n", agg_ie_len + agg_ssid_ie_len);
+ decode_info_elements(iebuf, agg_ie_len + agg_ssid_ie_len);
+#endif /* DEBUG_AGGREGATE */
+
+ /* do not forget to add the length of the SSID IE */
+ return agg_ie_len + agg_ssid_ie_len;
+
+} /* aggregate_info_elements() */
+
+
+
+
+
+/*
+ * ------------------------------------------------------------------------
+ *
+ * decode_info_elements
+ *
+ * Diagnostic routine to print out the Information Elements in a scan
+ * response.
+ *
+ * ------------------------------------------------------------------------
+ */
+#ifdef DEBUG_AGGREGATE
+static void
+decode_info_elements(const unsigned char *info, int infolen)
+{
+ const unsigned char *p = info;
+ int id, len;
+
+ while (p < (info + infolen))
+ {
+ int col;
+
+ id = *p++;
+ len = *p++;
+
+ printk(" %3d, %3d bytes: ", id, len);
+ col = 0;
+ while (len--) {
+ printk(" %02X", *p);
+ p++;
+
+ if (++col == 16) {
+ col = 0;
+ printk("\n ");
+ }
+ }
+ if (col) {
+ printk("\n");
+ }
+ }
+}
+#endif /* DEBUG_AGGREGATE */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/sme_native.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/sme_native.c
new file mode 100644
index 0000000..753a4d2
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/sme_native.c
@@ -0,0 +1,392 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: sme_native.c
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include "unifi_priv.h"
+#include "driver/conversions.h"
+
+
+int
+uf_sme_init(unifi_priv_t *priv)
+{
+ int r;
+
+ init_MUTEX(&priv->mlme_blocking_mutex);
+
+ r = uf_init_wext_interface(priv);
+ if (r != 0) {
+ return r;
+ }
+
+ /* Need a separate client for the background multicast process */
+ priv->multicast_client = ul_register_client(priv, 0, sme_native_mlme_event_handler);
+ if (priv->multicast_client == NULL) {
+ unifi_error(priv, "Failed to register WEXT as a unifi client\n");
+ return -1;
+ }
+
+ priv->mc_list_count_stored = 0;
+
+ return 0;
+} /* uf_sme_init() */
+
+
+void
+uf_sme_deinit(unifi_priv_t *priv)
+{
+ /* Free memory allocated for the scan table */
+ unifi_clear_scan_table(priv);
+
+ /* Unregister WEXT as a client. */
+ if (priv->multicast_client) {
+ ul_deregister_client(priv->multicast_client);
+ priv->multicast_client = NULL;
+ }
+
+ /* Cancel any pending workqueue tasks */
+ flush_workqueue(priv->unifi_workqueue);
+
+ uf_deinit_wext_interface(priv);
+
+} /* uf_sme_deinit() */
+
+
+int sme_mgt_wifi_on(unifi_priv_t *priv)
+{
+ int r;
+
+ if (priv == NULL) {
+ return -EINVAL;
+ }
+
+ r = uf_request_firmware_files(priv);
+ if (r) {
+ unifi_error(priv, "sme_mgt_wifi_on: Failed to get f/w\n");
+ return r;
+ }
+
+ /*
+ * The request to initialise UniFi might come while UniFi is running.
+ * We need to block all I/O activity until the reset completes, otherwise
+ * an SDIO error might occur resulting an indication to the SME which
+ * makes it think that the initialisation has failed.
+ */
+ priv->bh_thread.block_thread = 1;
+
+ /* Power on UniFi */
+ r = unifi_sdio_power_on(priv->sdio);
+ if (r < 0) {
+ return r;
+ }
+
+ /* Initialise UniFi hardware */
+ r = uf_init_hw(priv);
+ if (r) {
+ return r;
+ }
+
+ /* Start the I/O thread */
+ uf_init_bh(priv);
+
+ priv->init_progress = UNIFI_INIT_FW_DOWNLOADED;
+
+ return 0;
+}
+
+int
+sme_sys_suspend(unifi_priv_t *priv)
+{
+ /* Abort any pending requests. */
+ unifi_abort_mlme(priv);
+
+ /* Allow our mlme request to go through. */
+ priv->io_aborted = 0;
+
+ /* Send MLME-RESET.req to UniFi. */
+ unifi_reset_state(priv, priv->netdev->dev_addr, 0);
+
+ /* Stop the network traffic */
+ netif_carrier_off(priv->netdev);
+
+ /* Put UniFi to deep sleep */
+ uf_sdio_claim(priv->sdio);
+ unifi_force_low_power_mode(priv->card);
+ uf_sdio_release(priv->sdio);
+
+ return 0;
+} /* sme_sys_suspend() */
+
+
+int
+sme_sys_resume(unifi_priv_t *priv)
+{
+ /* Send disconnect event so clients will re-initialise connection. */
+ memset(priv->wext_conf.current_ssid, 0, UNIFI_MAX_SSID_LEN);
+ memset((void*)priv->wext_conf.current_bssid, 0, ETH_ALEN);
+ priv->wext_conf.capability = 0;
+ wext_send_disassoc_event(priv);
+
+ return 0;
+} /* sme_sys_resume() */
+
+
+#define ROWSTATUS_ACTIVE 1
+#define ROWSTATUS_NOT_IN_SERVICE 2
+
+#define dot11Address_oid "1.2.840.10036.2.3.1.2"
+#define dot11GroupAddressesStatus_oid "1.2.840.10036.2.3.1.3"
+
+void
+uf_multicast_list_wq(struct work_struct *work)
+{
+ unifi_priv_t *priv = container_of(work, unifi_priv_t,
+ multicast_list_task);
+
+ char oidstr[128];
+ u8 *mc_list = priv->mc_list;
+ int mc_list_count_to_store, r, i;
+
+ /* priv->mc_list_count is not persistent. use a local variable. */
+ mc_list_count_to_store = priv->mc_list_count;
+ /* Get pointer to the addresses list. */
+ mc_list = priv->mc_list;
+ /* Set list of valid addresses, if any. */
+ for (i = 1; i <= mc_list_count_to_store; i++)
+ {
+ snprintf(oidstr, 128, "%s.%d.%d", dot11Address_oid, priv->if_index, i);
+ r = unifi_set_mib_string(priv, priv->multicast_client, oidstr, mc_list, ETH_ALEN);
+ if (r < 0) {
+ continue;
+ }
+
+ snprintf(oidstr, 128, "%s.%d.%d", dot11GroupAddressesStatus_oid, priv->if_index, i);
+ r = unifi_set_mib_int(priv, priv->multicast_client,
+ oidstr, ROWSTATUS_ACTIVE);
+ if (r < 0) {
+ continue;
+ }
+
+ /* Advance pointer to next address. */
+ mc_list += ETH_ALEN;
+ }
+
+ /* Invalidate the rest of the address already stored in the UniFi's MIB. */
+ for (i = mc_list_count_to_store + 1; i <= priv->mc_list_count_stored; i++)
+ {
+ snprintf(oidstr, 128, "%s.%d.%d", dot11GroupAddressesStatus_oid, priv->if_index, i);
+ r = unifi_set_mib_int(priv, priv->multicast_client,
+ oidstr, ROWSTATUS_NOT_IN_SERVICE);
+ if (r < 0) {
+ continue;
+ }
+ }
+
+ /* Update our state. */
+ priv->mc_list_count_stored = priv->mc_list_count;
+
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * sme_native_log_event
+ *
+ * Callback function to be registered as the SME event callback.
+ * Copies the signal content into a new udi_log_t struct and adds
+ * it to the read queue for the SME client.
+ *
+ * Arguments:
+ * arg This is the value given to unifi_add_udi_hook, in
+ * this case a pointer to the client instance.
+ * signal Pointer to the received signal.
+ * signal_len Size of the signal structure in bytes.
+ * bulkdata Pointers to any associated bulk data.
+ * dir Direction of the signal. Zero means from host,
+ * non-zero means to host.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+sme_native_log_event(ul_client_t *pcli,
+ u8 *sig_packed, int sig_len,
+ const bulk_data_param_t *bulkdata,
+ int dir)
+{
+ unifi_priv_t *priv;
+ udi_log_t *logptr;
+ u8 *p;
+ int i, r;
+ int signal_len;
+ int total_len;
+ udi_msg_t *msgptr;
+ CSR_SIGNAL signal;
+ ul_client_t *client = pcli;
+
+ func_enter();
+
+ if (client == NULL) {
+ unifi_error(NULL, "sme_native_log_event: client has exited\n");
+ return;
+ }
+
+ priv = unifi_find_instance(client->instance);
+ if (!priv) {
+ unifi_error(priv, "invalid priv\n");
+ return;
+ }
+
+ /* Just a sanity check */
+ if ((sig_packed == NULL) || (sig_len <= 0)) {
+ return;
+ }
+
+ /* Get the unpacked signal */
+ r = read_unpack_signal(sig_packed, &signal);
+ if (r == 0) {
+ signal_len = SigGetSize(&signal);
+ } else {
+ /* The control indications are 1 byte, pass them to client */
+ if (sig_len == 1) {
+ unifi_trace(priv, UDBG5,
+ "Control indication (0x%x) for native SME.\n",
+ *sig_packed);
+
+ *(u8*)&signal = *sig_packed;
+ signal_len = sig_len;
+ } else {
+ unifi_error(priv, "Received unknown or corrupted signal.\n");
+ return;
+ }
+ }
+
+ unifi_trace(priv, UDBG3, "sme_native_log_event: signal %s for %d\n",
+ lookup_signal_name(signal.SignalPrimitiveHeader.SignalId),
+ client->client_id);
+
+ /* Discard some ma-unidata.ind */
+ if (signal.SignalPrimitiveHeader.SignalId == CSR_MA_UNITDATA_INDICATION_ID) {
+ return;
+ }
+ /* Discard ma-unidata-status.ind */
+ if (signal.SignalPrimitiveHeader.SignalId == CSR_MA_UNITDATA_CONFIRM_ID) {
+ return;
+ }
+
+ total_len = signal_len;
+ /* Calculate the buffer we need to store signal plus bulk data */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ total_len += bulkdata->d[i].data_length;
+ }
+
+ /* Allocate log structure plus actual signal. */
+ logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL);
+
+ if (logptr == NULL) {
+ unifi_error(priv,
+ "Failed to allocate %d bytes for a UDI log record\n",
+ sizeof(udi_log_t) + total_len);
+ return;
+ }
+
+ /* Fill in udi_log struct */
+ INIT_LIST_HEAD(&logptr->q);
+ msgptr = &logptr->msg;
+ msgptr->length = sizeof(udi_msg_t) + total_len;
+ msgptr->timestamp = jiffies_to_msecs(jiffies);
+ msgptr->direction = dir;
+ msgptr->signal_length = signal_len;
+
+ /* Copy signal and bulk data to the log */
+ p = (u8 *)(msgptr + 1);
+ memcpy(p, &signal, signal_len);
+ p += signal_len;
+
+ /* Append any bulk data */
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ int len = bulkdata->d[i].data_length;
+
+ /*
+ * Len here might not be the same as the length in the bulk data slot.
+ * The slot length will always be even, but len could be odd.
+ */
+ if (len > 0) {
+ if (bulkdata->d[i].os_data_ptr) {
+ memcpy(p, bulkdata->d[i].os_data_ptr, len);
+ } else {
+ memset(p, 0, len);
+ }
+ p += len;
+ }
+ }
+
+ /* Add to tail of log queue */
+ down(&client->udi_sem);
+ list_add_tail(&logptr->q, &client->udi_log);
+ up(&client->udi_sem);
+
+ /* Wake any waiting user process */
+ wake_up_interruptible(&client->udi_wq);
+
+ func_exit();
+
+} /* sme_native_log_event() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_ta_indicate_protocol
+ *
+ * Report that a packet of a particular type has been seen
+ *
+ * Arguments:
+ * drv_priv The device context pointer passed to ta_init.
+ * protocol The protocol type enum value.
+ * direction Whether the packet was a tx or rx.
+ * src_addr The source MAC address from the data packet.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * We defer the actual sending to a background workqueue,
+ * see uf_ta_ind_wq().
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_ta_indicate_protocol(void *ospriv,
+ unifi_traffic_packettype packet_type,
+ unifi_protocol_direction direction,
+ const unifi_MACAddress *src_addr)
+{
+
+} /* unifi_ta_indicate_protocol */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_ta_indicate_sampling
+ *
+ * Send the TA sampling information to the SME.
+ *
+ * Arguments:
+ * drv_priv The device context pointer passed to ta_init.
+ * stats The TA sampling data to send.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_ta_indicate_sampling(void *ospriv, unifi_traffic_stats *stats)
+{
+
+} /* unifi_ta_indicate_sampling() */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/unifi_native.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/unifi_native.h
new file mode 100644
index 0000000..b912a1f
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/unifi_native.h
@@ -0,0 +1,282 @@
+/*
+ *****************************************************************************
+ *
+ * FILE : unifi_native.h
+ *
+ * PURPOSE : Private header file for unifi driver support to wireless extensions.
+ *
+ * UDI = UniFi Debug Interface
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ *****************************************************************************
+ */
+#ifndef __LINUX_UNIFI_NATIVE_H__
+#define __LINUX_UNIFI_NATIVE_H__ 1
+
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+
+
+/*
+ * scan.c wext.c autojoin.c
+ */
+/* Structure to hold results of a scan */
+typedef struct scan_info {
+
+ CSR_MLME_SCAN_INDICATION msi;
+
+ unsigned char *info_elems;
+ int info_elem_length;
+
+} scan_info_t;
+
+
+#define IE_VECTOR_MAXLEN 1024
+
+/*
+ * Structre to hold the wireless network configuration info.
+ */
+
+struct wext_config {
+
+ /* Requested channel when setting up an adhoc network */
+ int channel;
+
+ /* wireless extns mode: IW_MODE_AUTO, ADHOC, INFRA, MASTER ... MONITOR */
+ int mode;
+
+ /* The capabilities of the currently joined network */
+ int capability;
+
+ /* The interval between beacons if we create an IBSS */
+ int beacon_period;
+
+ /*
+ * Power-save parameters
+ */
+ /* The listen interval to ask for in Associate req. */
+ int assoc_listen_interval;
+ /* Power-mode to put UniFi into */
+
+ unsigned char desired_ssid[UNIFI_MAX_SSID_LEN]; /* the last ESSID set by SIOCSIWESSID */
+ int power_mode;
+ /* Whether to wake for broadcast packets (using DTIM interval) */
+ int wakeup_for_dtims;
+
+ /* Currently selected WEP Key ID (0..3) */
+ int wep_key_id;
+
+ wep_key_t wep_keys[NUM_WEPKEYS];
+
+ CSR_AUTHENTICATION_TYPE auth_type;
+ int privacy;
+
+ u32 join_failure_timeout;
+ u32 auth_failure_timeout;
+ u32 assoc_failure_timeout;
+
+ unsigned char generic_ie[IE_VECTOR_MAXLEN];
+ int generic_ie_len;
+
+ struct iw_statistics wireless_stats;
+
+
+ /* the ESSID we are currently associated to */
+ unsigned char current_ssid[UNIFI_MAX_SSID_LEN];
+ /* the BSSID we are currently associated to */
+ unsigned char current_bssid[6];
+
+ /*
+ * IW_AUTH_WPA_VERSION_DISABLED 0x00000001
+ * IW_AUTH_WPA_VERSION_WPA 0x00000002
+ * IW_AUTH_WPA_VERSION_WPA2 0x00000004
+ */
+ unsigned char wpa_version;
+
+ /*
+ * cipher selection:
+ * IW_AUTH_CIPHER_NONE 0x00000001
+ * IW_AUTH_CIPHER_WEP40 0x00000002
+ * IW_AUTH_CIPHER_TKIP 0x00000004
+ * IW_AUTH_CIPHER_CCMP 0x00000008
+ * IW_AUTH_CIPHER_WEP104 0x00000010
+ */
+ unsigned char pairwise_cipher_used;
+ unsigned char group_cipher_used;
+
+ unsigned int frag_thresh;
+ unsigned int rts_thresh;
+
+ /* U-APSD value, send with Association Request to WMM Enabled APs */
+ unsigned char wmm_bss_uapsd_mask;
+ /* The WMM capabilities of the selected BSS */
+ unsigned int bss_wmm_capabilities;
+
+ /* Flag to prevent a join when the ssid is set */
+ int disable_join_on_ssid_set;
+
+ /* Scan info */
+#define UNIFI_MAX_SCANS 32
+ scan_info_t scan_list[UNIFI_MAX_SCANS];
+ int num_scan_info;
+
+ /* Flag on whether non-802.1x packets are allowed out */
+ unifi_PortAction block_controlled_port;
+
+ /* Flag on whether we have completed an authenticate/associate process */
+ unsigned int flag_associated : 1;
+}; /* struct wext_config */
+
+
+/*
+ * wext.c
+ */
+int mlme_set_protection(unifi_priv_t *priv, unsigned char *addr,
+ CSR_PROTECT_TYPE prot, CSR_KEY_TYPE key_type);
+
+
+/*
+ * scan.c
+ */
+void unifi_scan_indication_handler(unifi_priv_t *priv,
+ const CSR_MLME_SCAN_INDICATION *msg,
+ const unsigned char *extra,
+ unsigned int len);
+void unifi_clear_scan_table(unifi_priv_t *priv);
+scan_info_t *unifi_get_scan_report(unifi_priv_t *priv, int index);
+
+
+/*
+ * Utility functions
+ */
+const unsigned char *unifi_find_info_element(int id,
+ const unsigned char *info,
+ int len);
+int unifi_add_info_element(unsigned char *info,
+ int ie_id,
+ const unsigned char *ie_data,
+ int ie_len);
+
+/*
+ * autojoin.c
+ */
+/* Higher level fns */
+int unifi_autojoin(unifi_priv_t *priv, const char *ssid);
+int unifi_do_scan(unifi_priv_t *priv, int scantype, CSR_BSS_TYPE bsstype,
+ const char *ssid, int ssid_len);
+
+int unifi_set_powermode(unifi_priv_t *priv);
+int unifi_join_ap(unifi_priv_t *priv, scan_info_t *si);
+int unifi_join_bss(unifi_priv_t *priv, unsigned char *macaddr);
+int unifi_leave(unifi_priv_t *priv);
+
+/*
+ * Status and management.
+ */
+int uf_init_wext_interface(unifi_priv_t *priv);
+void uf_deinit_wext_interface(unifi_priv_t *priv);
+
+/*
+ * Function to reset UniFi's 802.11 state by sending MLME-RESET.req
+ */
+int unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr, unsigned char set_default_mib);
+
+
+/*
+ * mib.c
+ */
+int unifi_set_mib(unifi_priv_t *priv, ul_client_t *pcli,
+ unsigned char *varbind);
+int unifi_get_mib(unifi_priv_t *priv, ul_client_t *pcli,
+ unsigned char *varbind, int maxlen);
+
+/* Convenience MIB functions */
+int unifi_set_mib_string(unifi_priv_t *priv, ul_client_t *pcli,
+ char *oidstr, unsigned char *value, int len);
+int unifi_set_mib_int(unifi_priv_t *priv, ul_client_t *pcli,
+ char *oidstr, int value);
+int unifi_get_mib_int(unifi_priv_t *priv, ul_client_t *pcli,
+ char *oidstr, int *valuep);
+
+
+/*
+ * mlme.c
+ */
+/* Abort an MLME operation - useful in error recovery */
+int unifi_abort_mlme(unifi_priv_t *priv);
+
+int unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli,
+ CSR_SIGNAL *sig, bulk_data_param_t *data_ptrs,
+ int timeout);
+void unifi_mlme_copy_reply_and_wakeup_client(ul_client_t *pcli,
+ CSR_SIGNAL *signal, int signal_len,
+ const bulk_data_param_t *bulkdata);
+
+int unifi_mlme_reset(unifi_priv_t *priv, ul_client_t *pcli,
+ unsigned char *macaddr, unsigned char set_default_mib);
+/*
+ * Utility functions
+ */
+const char *lookup_reason_code(int reason);
+const char *lookup_result_code(int result);
+
+
+/*
+ * sme_native.c
+ */
+int uf_sme_init(unifi_priv_t *priv);
+void uf_sme_deinit(unifi_priv_t *priv);
+int sme_sys_suspend(unifi_priv_t *priv);
+int sme_sys_resume(unifi_priv_t *priv);
+int sme_mgt_wifi_on(unifi_priv_t *priv);
+
+/* Callback for event logging to SME clients (unifi_manager) */
+void sme_native_log_event(ul_client_t *client,
+ u8 *sig_packed, int sig_len,
+ const bulk_data_param_t *bulkdata,
+ int dir);
+
+void sme_native_mlme_event_handler(ul_client_t *pcli,
+ u8 *sig_packed, int sig_len,
+ const bulk_data_param_t *bulkdata,
+ int dir);
+
+/* The workqueue task to set the multicast addresses list */
+void uf_multicast_list_wq(struct work_struct *work);
+
+/* Task to query statistics from the MIB */
+#define UF_SME_STATS_WQ_TIMEOUT 2000 /* in msecs */
+void uf_sme_stats_wq(struct work_struct *work);
+
+/*
+ * Choose one of these if available in linux/if_arp.h:
+ * #define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_RADIOTAP
+ * #define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_PRISM
+ *
+ * Radiotap is the newer standard for softmac WLAN devices, it works with
+ * Wireshark but not Ethereal (due to a bug in the Ethereal dissector).
+ * Prism is an older (less desirable) format but it does work with Ethereal.
+ */
+#ifdef ARPHRD_IEEE80211_RADIOTAP
+#define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_RADIOTAP
+#else
+#ifdef ARPHRD_IEEE80211_PRISM
+#define UNIFI_SNIFF_ARPHRD ARPHRD_IEEE80211_PRISM
+#endif
+#endif
+
+#ifdef UNIFI_SNIFF_ARPHRD
+/*
+ * monitor.c
+ */
+int uf_start_sniff(unifi_priv_t *priv);
+void ma_sniffdata_ind(void *ospriv,
+ const CSR_MA_SNIFFDATA_INDICATION *ind,
+ const bulk_data_param_t *bulkdata);
+#endif /* ARPHRD_IEEE80211_PRISM */
+
+#endif /* __LINUX_UNIFI_NATIVE_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/wext.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/wext.c
new file mode 100644
index 0000000..165833f
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_native/wext.c
@@ -0,0 +1,3246 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: wext.c
+ *
+ * PURPOSE:
+ * Handlers for ioctls from iwconfig.
+ * These provide the control plane operations.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/types.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+#include "driver/unifi.h"
+#include "driver/conversions.h"
+#include "unifi_priv.h"
+
+#define IWPRIV_POWER_SAVE_MAX_STRING 32
+#define SIOCIWS80211POWERSAVEPRIV SIOCIWFIRSTPRIV
+#define SIOCIWG80211POWERSAVEPRIV SIOCIWFIRSTPRIV + 1
+
+#define MAX_WPA_IE_LEN 64
+
+/* The first channel in the 5GHz WLAN band */
+#define FIRST_5GHZ_CHANNEL 32
+
+
+/* MIB definitions */
+#define dot11WEPDefaultKeyValue "1.2.840.10036.1.3.1.2"
+#define dot11PrivacyInvoked "1.2.840.10036.1.5.1.1"
+#define dot11WEPDefaultKeyID "1.2.840.10036.1.5.1.2"
+#define dot11RSNAEnabled "1.2.840.10036.1.5.1.7"
+
+#define unifiRSSI "1.3.6.1.4.1.22164.1.1.3.6.1"
+#define unifiSNR "1.3.6.1.4.1.22164.1.1.3.6.3"
+#define unifiTxDataRate "1.3.6.1.4.1.22164.1.1.3.6.5"
+#define unifiFixTxDataRate "1.3.6.1.4.1.22164.1.1.4.1.10"
+#define unifiFixMaxTxDataRate "1.3.6.1.4.1.22164.1.1.4.1.11"
+
+#define dot11RTSThreshold "1.2.840.10036.2.1.1.2"
+#define dot11FragmentationThreshold "1.2.840.10036.2.1.1.5"
+#define dot11RSNAConfigGroupCipher "1.2.840.10036.1.9.1.4"
+#define unifiMLMEFaultReportLevel "1.3.6.1.4.1.22164.1.1.1.2"
+
+
+#define CHECK_INITED(_priv) \
+do { \
+ if (_priv->init_progress != UNIFI_INIT_COMPLETED) { \
+ return -ENODEV; \
+ } \
+} while (0)
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * Helper functions
+ * ---------------------------------------------------------------------------
+ */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * wext_freq_to_channel
+ * channel_to_mhz
+ *
+ * These functions convert between channel number and frequency.
+ *
+ * Arguments:
+ * ch Channel number, as defined in 802.11 specs
+ * m, e Mantissa and exponent as provided by wireless extension.
+ *
+ * Returns:
+ * channel or frequency (in MHz) value
+ * ---------------------------------------------------------------------------
+ */
+static int
+wext_freq_to_channel(int m, int e)
+{
+ int mhz;
+
+ mhz = m;
+ while (e < 6) {
+ mhz /= 10;
+ e++;
+ }
+ while (e > 6) {
+ mhz *= 10;
+ e--;
+ }
+
+ if (mhz >= 5000) {
+ return ((mhz - 5000) / 5);
+ }
+
+ if (mhz == 2482) {
+ return 14;
+ }
+
+ if (mhz >= 2407) {
+ return ((mhz - 2407) / 5);
+ }
+
+ return 0;
+} /* wext_freq_to_channel() */
+
+static int
+channel_to_mhz(int ch, int dot11a)
+{
+
+ if (ch == 0) return 0;
+ if (ch > 200) return 0;
+
+ /* 5G */
+ if (dot11a) {
+ return (5000 + (5 * ch));
+ }
+
+ /* 2.4G */
+ if (ch == 14) {
+ return 2484;
+ }
+
+ if ((ch < 14) && (ch > 0)) {
+ return (2407 + (5 * ch));
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_wep_key
+ *
+ * Send the given WEP key to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * keynum Which key to set, 1..4.
+ * keyval Value of the key to set
+ * keylen Number of bytes in the key.
+ *
+ * Returns:
+ * 0 on success, linux error code on error.
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_wep_key(unifi_priv_t *priv, int keynum, u8 *keyval, int keylen)
+{
+ char oidstr[128];
+ int err;
+
+ snprintf(oidstr, 128, "%s.%d.%d",
+ dot11WEPDefaultKeyValue, priv->if_index, keynum);
+
+ err = unifi_set_mib_string(priv, priv->wext_client, oidstr, keyval, keylen);
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ /* save key for GIWENCODE */
+ priv->wext_conf.wep_keys[keynum-1].len = keylen;
+ memcpy(priv->wext_conf.wep_keys[keynum-1].key, keyval, keylen);
+
+ return 0;
+} /* set_wep_key() */
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_default_wep_key
+ *
+ * Set the default WEP key to use.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * keynum Which key to set, 0..3.
+ *
+ * Returns:
+ * 0 on success, linux error code on error.
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_default_wep_key(unifi_priv_t *priv, int keynum)
+{
+ char oidstr[128];
+ int err;
+
+ snprintf(oidstr, 128, "%s.%d",
+ dot11WEPDefaultKeyID, priv->if_index);
+
+ err = unifi_set_mib_int(priv, priv->wext_client, oidstr, keynum);
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ return 0;
+} /* set_default_wep_key() */
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_privacy_invoked
+ *
+ * Send a WEP-enable MIB to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * enable Enable WEP if non-zero.
+ *
+ * Returns:
+ * 0 on success, linux error code on error.
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_privacy_invoked(unifi_priv_t *priv, int privacy)
+{
+ char oidstr[128];
+ int err;
+
+ /* Build the OID string by appending the if_index */
+ snprintf(oidstr, 128, "%s.%d", dot11PrivacyInvoked, priv->if_index);
+
+ if (privacy) {
+ err = unifi_set_mib_int(priv, priv->wext_client, oidstr, 1);
+ } else {
+ err = unifi_set_mib_int(priv, priv->wext_client, oidstr, 2); /* MIB false ! */
+ }
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ priv->wext_conf.privacy = privacy;
+
+ return err;
+} /* set_privacy_invoked() */
+
+#if 0
+static int
+set_mlme_fault_report_level(unifi_priv_t *priv, int fault_level)
+{
+ int err;
+
+ err = unifi_set_mib_int(priv, priv->wext_client, unifiMLMEFaultReportLevel, fault_level);
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ return 0;
+} /* set_mlme_fault_report_level */
+#endif /* 0 */
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_rsna_config_group_cipher
+ *
+ * Send the supported group cipher suite MIB to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * wpa_mode WPA or RSN mode.
+ * group_cipher The desired group cipher suite
+ *
+ * Returns:
+ * 0 on success, linux error code on error.
+ * ---------------------------------------------------------------------------
+ */
+#if WIRELESS_EXT > 17
+static int
+set_rsna_config_group_cipher(unifi_priv_t *priv, unsigned char wpa_mode, int group_cipher)
+{
+ const unsigned char WPA_OUI[3] = {0x00, 0x50, 0xf2};
+ const unsigned char RSN_OUI[3] = {0x00, 0x0f, 0xac};
+ char oidstr[128];
+ unsigned char cipher[4];
+ int err;
+
+ /*
+ * Translate the group cipher suite set the wpa_supplicant,
+ * to 802.11i IE cipher suite values.
+ */
+ switch (group_cipher) {
+ case 0x01:
+ cipher[3] = (unsigned char)0x00;
+ break;
+ case 0x02:
+ cipher[3] = (unsigned char)0x01;
+ break;
+ case 0x04:
+ cipher[3] = (unsigned char)0x02;
+ break;
+ case 0x08:
+ cipher[3] = (unsigned char)0x04;
+ break;
+ case 0x10:
+ cipher[3] = (unsigned char)0x05;
+ break;
+ default:
+ return 0;
+ }
+
+ /* Create the OUI+SC for setting to the MIB */
+ switch (wpa_mode) {
+ case 2:
+ memcpy(cipher, WPA_OUI, 3);
+ break;
+
+ case 4:
+ memcpy(cipher, RSN_OUI, 3);
+ break;
+
+ default:
+ return 0;
+ }
+
+ /* Build the OID string by appending the if_index */
+ snprintf(oidstr, 128, "%s.%d", dot11RSNAConfigGroupCipher, priv->if_index);
+
+ err = unifi_set_mib_string(priv, priv->wext_client, oidstr, cipher, 4);
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ return 0;
+} /* set_rsna_config_group_cipher() */
+#endif /* WIRELESS_EXT > 17 */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_rts_threshold
+ *
+ * Send the RTS threshold MIB to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * rts_value Value of the RTS threshold. 0...2347
+ *
+ * Returns:
+ * 0 on success, linux error code on error.
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_rts_threshold(unifi_priv_t *priv, int rts_value)
+{
+ char oidstr[128];
+ int err;
+
+ /* Build the OID string by appending the if_index */
+ snprintf(oidstr, 128, "%s.%d", dot11RTSThreshold, priv->if_index);
+
+ err = unifi_set_mib_int(priv, priv->wext_client, oidstr, rts_value);
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ /* Store the new threshold to the private data */
+ priv->wext_conf.rts_thresh = rts_value;
+
+ return 0;
+} /* set_rts_threshold */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_fragmentation_threshold
+ *
+ * Send the Fragmentation threshold MIB to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * frag_value Value of the RTS threshold. 256...2346
+ *
+ * Returns:
+ * 0 on success, linux error code on error.
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_fragmentation_threshold(unifi_priv_t *priv, int frag_value)
+{
+ char oidstr[128];
+ int err;
+
+ /* Build the OID string by appending the if_index */
+ snprintf(oidstr, 128, "%s.%d", dot11FragmentationThreshold, priv->if_index);
+
+ /* Fragmentation Threshold must be even */
+ err = unifi_set_mib_int(priv, priv->wext_client, oidstr, (frag_value & ~0x1));
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ /* Store the new threshold to the private data */
+ priv->wext_conf.frag_thresh = (frag_value & ~0x1);
+
+ return 0;
+} /* set_fragmentation_threshold */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_rsna_enabled
+ *
+ * Send a WEP-enable MIB to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * enable Enable WEP if non-zero.
+ *
+ * Returns:
+ * 0 on success, linux error code on error.
+ * ---------------------------------------------------------------------------
+ */
+#if WIRELESS_EXT > 17
+static int
+set_rsna_enabled(unifi_priv_t *priv, int enabled)
+{
+ char oidstr[128];
+ int err;
+
+ /* Build the OID string by appending the if_index */
+ snprintf(oidstr, 128, "%s.%d", dot11RSNAEnabled, priv->if_index);
+
+ if (enabled) {
+ err = unifi_set_mib_int(priv, priv->wext_client, oidstr, 1);
+ } else {
+ err = unifi_set_mib_int(priv, priv->wext_client, oidstr, 2); /* MIB false ! */
+ }
+
+ if (err < 0) {
+ return -EIO;
+ }
+ if (err > 0) {
+ return -EINVAL;
+ }
+
+ return 0;
+} /* set_rsna_enabled() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * set_rsn_key
+ *
+ * Send a RSNA (i.e. WPA/WPA2) key to UniFi.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+set_rsn_key(unifi_priv_t *priv, unsigned char *addr,
+ int algorithm,
+ int keyid, unsigned char *keydata, int key_len,
+ CSR_KEY_TYPE key_type, unsigned char *rx_seq)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_SETKEYS_REQUEST *req = &signal.u.MlmeSetkeysRequest;
+ bulk_data_param_t data_ptrs;
+ unsigned char *CSS;
+ int timeout = 1000;
+ int r;
+ ul_client_t *pcli = priv->wext_client;
+ unsigned char *request_buf = NULL;
+ unsigned int request_len = key_len;
+
+ req->Length = key_len * 8; /* in bits */
+ req->KeyId = keyid;
+ req->KeyType = key_type;
+ memcpy(&req->Address, addr, ETH_ALEN);
+
+ /* Receive Sequence Count (RSC) */
+ if (rx_seq) {
+ memcpy(&req->ReceiveSequenceCount, rx_seq, 8);
+ } else {
+ memset(&req->ReceiveSequenceCount, 0, 8);
+ }
+
+ /*
+ * AuthenticatorSupplicantOrInitiatorPeer
+ * As a station in a Managed network, we are always the Supplicant.
+ * If we ever use RSN in an IBSS, we might be the Authenticator.
+ */
+ req->AuthenticatorSupplicantOrInitiatorPeer = 0;
+
+
+ /* Set up Cipher Suite Selector */
+ CSS = (unsigned char *)&req->CipherSuiteSelector;
+ switch (priv->wext_conf.wpa_version) {
+ case IW_AUTH_WPA_VERSION_WPA:
+ CSS[0] = 0x00;
+ CSS[1] = 0x50;
+ CSS[2] = 0xF2;
+ break;
+ case IW_AUTH_WPA_VERSION_WPA2:
+ CSS[0] = 0x00;
+ CSS[1] = 0x0F;
+ CSS[2] = 0xAC;
+ }
+ switch (algorithm) {
+ /* IW_ENCODE_ALG_NONE, IW_ENCODE_ALG_WEP handled above */
+ case IW_ENCODE_ALG_TKIP:
+ CSS[3] = 0x02;
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ CSS[3] = 0x04;
+ break;
+ default:
+ unifi_trace(priv, UDBG1, KERN_ERR "Invalid WE encrpytion algorithm: %d\n", algorithm);
+ return -EINVAL;
+ }
+
+ unifi_trace(priv, UDBG1, "SETKEYS: key %d, len %d, CSS=%02x:%02x:%02x:%02x\n"
+ " addr=%02x:%02x:%02x:%02x:%02x:%02x, RSC=%lld\n",
+ keyid, key_len,
+ CSS[0], CSS[1], CSS[2], CSS[3],
+ req->Address.x[0], req->Address.x[1], req->Address.x[2],
+ req->Address.x[3], req->Address.x[4], req->Address.x[5],
+ req->ReceiveSequenceCount);
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SETKEYS_REQUEST_ID;
+
+ if (request_len) {
+ r = unifi_net_data_malloc(priv, &data_ptrs.d[0], request_len);
+ if (r != 0) {
+ unifi_error(priv, "set_rsn_key: failed to allocatd request_buf.\n");
+ return -EIO;
+ }
+ request_buf = (unsigned char*)data_ptrs.d[0].os_data_ptr;
+
+ memcpy(request_buf, keydata, request_len);
+ }
+
+ /* Do not mess with data_ptrs.d[0].os_net_buf_ptr. */
+ data_ptrs.d[0].os_data_ptr = request_buf;
+ data_ptrs.d[0].data_length = request_len;
+ data_ptrs.d[1].os_data_ptr = data_ptrs.d[1].os_net_buf_ptr = NULL;
+ data_ptrs.d[1].data_length = 0;
+
+ /*
+ * Queue request to UniFi and wait for confirm.
+ */
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, &data_ptrs, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send SETKEYS request, error %d\n", r);
+ return r;
+ }
+
+ r = pcli->reply_signal->u.MlmeSetkeysConfirm.ResultCode;
+ if (r) {
+ unifi_notice(priv, "SETKEYS request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ return -EIO;
+ }
+
+
+ return 0;
+} /* set_rsn_key() */
+
+#endif /* WIRELESS_EXT > 17 */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * mlme_set_protection
+ *
+ * Send a SETPROTECTION MLME command to UniFi.
+ *
+ * Arguments:
+ * priv Pointer to driver private struct
+ * prot The protection to set:
+ * CSR_PT_NONE
+ * CSR_PT_RX
+ * CSR_PT_TX
+ * CSR_PT_RX_TX
+ * key_type Key type, one of:
+ * CSR_GROUP
+ * CSR_PAIRWISE
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int
+mlme_set_protection(unifi_priv_t *priv, unsigned char *addr,
+ CSR_PROTECT_TYPE prot, CSR_KEY_TYPE key_type)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_SETPROTECTION_REQUEST *req = &signal.u.MlmeSetprotectionRequest;
+ int r;
+ int timeout = 1000;
+ ul_client_t *pcli = priv->wext_client;
+
+ unifi_trace(priv, UDBG1, "SETPROTECTION: addr: %02x:%02x:%02x:%02x:%02x:%02x prot %d, type %d\n",
+ addr[0], addr[1], addr[2],
+ addr[3], addr[4], addr[5],
+ prot, key_type);
+
+ memcpy(&req->Address, addr, ETH_ALEN);
+ req->ProtectType = prot;
+ req->KeyType = key_type;
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SETPROTECTION_REQUEST_ID;
+
+ r = unifi_mlme_blocking_request(priv, pcli, &signal, NULL, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send SETPROTECTION request, error %d\n", r);
+ return r;
+ }
+
+ r = pcli->reply_signal->u.MlmeSetprotectionConfirm.ResultCode;
+ if (r) {
+ unifi_notice(priv, "SETPROTECTION request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ return -EIO;
+ }
+
+ return 0;
+} /* mlme_set_protection() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * WEXT methods
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_giwname - handler for SIOCGIWNAME
+ * unifi_siwfreq - handler for SIOCSIWFREQ
+ * unifi_giwfreq - handler for SIOCGIWFREQ
+ * unifi_siwmode - handler for SIOCSIWMODE
+ * unifi_giwmode - handler for SIOCGIWMODE
+ * unifi_giwrange - handler for SIOCGIWRANGE
+ * unifi_siwap - handler for SIOCSIWAP
+ * unifi_giwap - handler for SIOCGIWAP
+ * unifi_siwscan - handler for SIOCSIWSCAN
+ * unifi_giwscan - handler for SIOCGIWSCAN
+ * unifi_siwessid - handler for SIOCSIWESSID
+ * unifi_giwessid - handler for SIOCGIWESSID
+ * unifi_siwencode - handler for SIOCSIWENCODE
+ * unifi_giwencode - handler for SIOCGIWENCODE
+ *
+ * Handler functions for IW extensions.
+ * These are registered via the unifi_iw_handler_def struct below
+ * and called by the generic IW driver support code.
+ * See include/net/iw_handler.h.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+
+
+static int
+iwprivs80211ps(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r = 0;
+ int ps_mode = *extra;
+
+ CHECK_INITED(priv);
+
+ unifi_trace(priv, UDBG1, "iwprivs80211ps: power save mode = %d\n", ps_mode);
+
+ /* Set power-saving mode if requested */
+ if (priv->wext_conf.power_mode != ps_mode) {
+ priv->wext_conf.power_mode = ps_mode;
+
+ r = unifi_set_powermode(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ /* Configure deep sleep signaling */
+ if (priv->wext_conf.power_mode || (priv->connected == UnifiNotConnected)) {
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_ENABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+ } else {
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_DISABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+ }
+ }
+
+ return 0;
+}
+
+static int
+iwprivg80211ps(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ CHECK_INITED(priv);
+
+ switch (priv->wext_conf.power_mode) {
+ case CSR_PMM_ACTIVE_MODE:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Active)", priv->wext_conf.power_mode);
+ break;
+ case CSR_PMM_FAST_POWER_SAVE:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Fast)", priv->wext_conf.power_mode);
+ break;
+ case CSR_PMM_POWER_SAVE:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Full)", priv->wext_conf.power_mode);
+ break;
+ default:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Unknown)", priv->wext_conf.power_mode);
+ break;
+ }
+
+ wrqu->data.length = strlen(extra) + 1;
+
+ return 0;
+}
+
+
+static int
+unifi_giwname(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ char *name = wrqu->name;
+
+ if (priv->if_index == CSR_INDEX_5G) {
+ strcpy(name, "IEEE 802.11-a");
+ } else {
+ strcpy(name, "IEEE 802.11-b/g");
+ }
+ return 0;
+} /* unifi_giwname() */
+
+
+static int
+unifi_siwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_freq *freq = (struct iw_freq *)wrqu;
+ int err = 0;
+
+ func_enter();
+
+ if ((freq->e == 0) && (freq->m <= 1000)) {
+ priv->wext_conf.channel = freq->m;
+ } else {
+ priv->wext_conf.channel = wext_freq_to_channel(freq->m, freq->e);
+ }
+
+ func_exit();
+ return err;
+} /* unifi_siwfreq() */
+
+
+static int
+unifi_giwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_freq *freq = (struct iw_freq *)wrqu;
+ int err = 0;
+
+ func_enter();
+
+ freq->m = priv->wext_conf.channel;
+ freq->e = 0;
+
+ func_exit();
+ return err;
+} /* unifi_giwfreq() */
+
+
+static int
+unifi_siwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err;
+ struct wext_config *wext = &priv->wext_conf;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ /*
+ * Send an MLME-RESET when changing mode with SetDefaultMIB set to 1.
+ * This will force the f/w to reset the MIBs to the values we have
+ * set before the initial MLME-RESET.
+ */
+ err = unifi_reset_state(priv, dev->dev_addr, 1);
+
+ /* All previously set 802.11 parameters are cleared. */
+ wext->channel = -1;
+ wext->capability = 0;
+ wext->power_mode = 0;
+ wext->wakeup_for_dtims = 1;
+ wext->wep_key_id = 0;
+ wext->auth_type = CSR_OPEN_SYSTEM;
+ /* default privacy to "off". */
+ wext->privacy = 0;
+ wext->generic_ie_len = 0;
+ wext->wpa_version = IW_AUTH_WPA_VERSION_DISABLED;
+ wext->pairwise_cipher_used = IW_AUTH_CIPHER_NONE;
+ wext->group_cipher_used = IW_AUTH_CIPHER_NONE;
+ wext->frag_thresh = 2346;
+ wext->rts_thresh = 2346;
+ wext->disable_join_on_ssid_set = 0;
+ memset(wext->desired_ssid, 0, UNIFI_MAX_SSID_LEN);
+ memset(wext->current_ssid, 0, UNIFI_MAX_SSID_LEN);
+ memset(wext->current_bssid, 0, 6);
+
+
+ wext->mode = wrqu->mode;
+
+ if (wext->mode == IW_MODE_MONITOR) {
+#ifdef UNIFI_SNIFF_ARPHRD
+ /*
+ * In monitor mode we will deliver Radiotap IEEE802.11
+ * frames to the stack.
+ */
+ dev->type = UNIFI_SNIFF_ARPHRD;
+#endif
+ } else {
+ /*
+ * If not in monitor mode, make sure frame MAC header type
+ * is reset to Ethernet.
+ */
+ dev->type = ARPHRD_ETHER;
+ }
+
+ func_exit();
+ if (err) {
+ return -EIO;
+ }
+ return 0;
+} /* unifi_siwmode() */
+
+
+
+static int
+unifi_giwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err = 0;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ wrqu->mode = priv->wext_conf.mode;
+
+ unifi_trace(priv, UDBG1, "reporting mode = %d\n", priv->wext_conf.mode);
+ func_exit();
+ return err;
+} /* unifi_giwmode() */
+
+
+
+static int
+unifi_giwrange(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *dwrq = &wrqu->data;
+ struct iw_range *range = (struct iw_range *) extra;
+ int i;
+
+ dwrq->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(*range));
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x0000;
+
+ /*
+ * Don't report the frequency/channel table, then the channel
+ * number returned elsewhere will be printed as a channel number.
+ */
+
+ /* Ranges of values reported in quality structs */
+ range->max_qual.qual = 40; /* Max expected qual value */
+ range->max_qual.level = -120; /* Noise floor in dBm */
+ range->max_qual.noise = -120; /* Noise floor in dBm */
+
+
+ /* space for IW_MAX_BITRATES (8 up to WE15, 32 later) */
+ i = 0;
+#if WIRELESS_EXT > 15
+ range->bitrate[i++] = 2 * 500000;
+ range->bitrate[i++] = 4 * 500000;
+ range->bitrate[i++] = 11 * 500000;
+ range->bitrate[i++] = 22 * 500000;
+ range->bitrate[i++] = 12 * 500000;
+ range->bitrate[i++] = 18 * 500000;
+ range->bitrate[i++] = 24 * 500000;
+ range->bitrate[i++] = 36 * 500000;
+ range->bitrate[i++] = 48 * 500000;
+ range->bitrate[i++] = 72 * 500000;
+ range->bitrate[i++] = 96 * 500000;
+ range->bitrate[i++] = 108 * 500000;
+#else
+ range->bitrate[i++] = 2 * 500000;
+ range->bitrate[i++] = 4 * 500000;
+ range->bitrate[i++] = 11 * 500000;
+ range->bitrate[i++] = 22 * 500000;
+ range->bitrate[i++] = 24 * 500000;
+ range->bitrate[i++] = 48 * 500000;
+ range->bitrate[i++] = 96 * 500000;
+ range->bitrate[i++] = 108 * 500000;
+#endif /* WIRELESS_EXT < 16 */
+ range->num_bitrates = i;
+
+ range->max_encoding_tokens = NUM_WEPKEYS;
+ range->num_encoding_sizes = 2;
+ range->encoding_size[0] = 5;
+ range->encoding_size[1] = 13;
+
+ range->we_version_source = 20;
+ range->we_version_compiled = WIRELESS_EXT;
+
+ /* Number of channels available in h/w */
+ range->num_channels = 14;
+ /* Number of entries in freq[] array */
+ range->num_frequency = 14;
+ for (i = 0; i < range->num_frequency; i++) {
+ int chan = i + 1;
+ range->freq[i].i = chan;
+ range->freq[i].m = channel_to_mhz(chan, 0);
+ range->freq[i].e = 6;
+ }
+
+#if WIRELESS_EXT > 16
+ /* Event capability (kernel + driver) */
+ range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+ IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
+ IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+ IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
+ range->event_capa[1] = IW_EVENT_CAPA_K_1;
+ range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
+ IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
+ IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
+ IW_EVENT_CAPA_MASK(IWEVEXPIRED));
+#endif /* WIRELESS_EXT > 16 */
+
+#if WIRELESS_EXT > 17
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif /* WIRELESS_EXT > 17 */
+
+
+ return 0;
+} /* unifi_giwrange() */
+
+
+static int
+unifi_siwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err = 0;
+ unsigned char ap_bssid[ETH_ALEN];
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) {
+ return -EINVAL;
+ }
+
+ LOCK_DRIVER(priv);
+
+ memcpy(ap_bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
+
+ unifi_trace(priv, UDBG1, "siwap: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ap_bssid[0],
+ ap_bssid[1],
+ ap_bssid[2],
+ ap_bssid[3],
+ ap_bssid[4],
+ ap_bssid[5]);
+
+ if (((ap_bssid[0] | ap_bssid[1] | ap_bssid[2] | ap_bssid[3] | ap_bssid[4] | ap_bssid[5]) != 0) &&
+ ((ap_bssid[0] & ap_bssid[1] & ap_bssid[2] & ap_bssid[3] & ap_bssid[4] & ap_bssid[5]) != 0xFF))
+ {
+ err = unifi_join_bss(priv, ap_bssid);
+ }
+
+ UNLOCK_DRIVER(priv);
+
+ func_exit();
+
+ return err;
+} /* unifi_siwap() */
+
+
+static int
+unifi_giwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ CHECK_INITED(priv);
+
+ wrqu->ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(wrqu->ap_addr.sa_data, priv->wext_conf.current_bssid, ETH_ALEN);
+
+ /* We don't do anything with this yet */
+ return 0;
+} /* unifi_giwap() */
+
+
+static int
+unifi_siwscan(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int scantype;
+ int r;
+ u8 *ssid = NULL;
+ int ssid_len = 0;
+#if WIRELESS_EXT > 17
+ struct iw_point *data = &wrqu->data;
+ struct iw_scan_req *req = (struct iw_scan_req *) extra;
+#endif
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+#if WIRELESS_EXT > 15
+ if (priv->wext_conf.mode == IW_MODE_MONITOR) {
+ scantype = UNIFI_SCAN_PASSIVE;
+ } else
+#endif /* WIRELESS_EXT */
+ {
+ scantype = UNIFI_SCAN_ACTIVE;
+ }
+
+#if WIRELESS_EXT > 17
+ if (req && (data->flags & IW_SCAN_THIS_ESSID)) {
+ ssid = req->essid;
+ ssid_len = req->essid_len;
+ unifi_trace(priv, UDBG1, "SIWSCAN: Scanning for %.*s\n", ssid_len, ssid);
+ } else
+#endif
+ {
+ unifi_trace(priv, UDBG1, "SIWSCAN: Scanning for all APs\n");
+ }
+
+ LOCK_DRIVER(priv);
+
+ r = unifi_do_scan(priv, scantype, CSR_ANY_BSS, ssid, ssid_len);
+
+ if (r == 0) {
+ wext_send_scan_results_event(priv);
+ }
+
+ UNLOCK_DRIVER(priv);
+
+ func_exit();
+
+ return r;
+
+} /* unifi_siwscan() */
+
+
+
+
+/*
+ * Translate scan data returned from the card to a card independent
+ * format that the Wireless Tools will understand
+ */
+static inline int
+unifi_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ char *current_ev, char *end_buf,
+ scan_info_t *si,
+ int scan_index)
+{
+ struct iw_event iwe; /* Temporary buffer */
+ unsigned char *info_elems;
+ CSR_MLME_SCAN_INDICATION *msi;
+ int info_elem_len;
+ const unsigned char *elem;
+ u16 capabilities;
+ int signal, noise, snr;
+ char *start_buf = current_ev;
+ char *current_val; /* For rates */
+ int i, r;
+
+ msi = &(si->msi);
+ info_elems = si->info_elems;
+ info_elem_len = si->info_elem_length;
+
+ /* get capinfo bits */
+ capabilities = (s16)unifi2host_16(msi->CapabilityInformation);
+
+ /* First entry *MUST* be the AP MAC address */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, msi->Bssid.x, ETH_ALEN);
+ iwe.len = IW_EV_ADDR_LEN;
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_ADDR_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ /* find SSID in Info Elems */
+ elem = unifi_find_info_element(IE_SSID_ID, info_elems, info_elem_len);
+ if (elem) {
+ int e_len = elem[1];
+ const unsigned char *e_ptr = elem + 2;
+ unsigned char buf[33];
+
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.essid.length = e_len;
+ if (iwe.u.essid.length > 32) {
+ iwe.u.essid.length = 32;
+ }
+ iwe.u.essid.flags = scan_index;
+ memcpy(buf, e_ptr, iwe.u.essid.length);
+ buf[iwe.u.essid.length] = '\0';
+ r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, buf);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+ }
+
+ /* Add mode */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWMODE;
+ if (msi->BssType == CSR_INFRASTRUCTURE) {
+ iwe.u.mode = IW_MODE_INFRA;
+ } else {
+ iwe.u.mode = IW_MODE_ADHOC;
+ }
+ iwe.len = IW_EV_UINT_LEN;
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_UINT_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+ /* Add frequency. iwlist will convert to channel using table given in giwrange */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = unifi2host_16(msi->ChannelFrequency);
+ iwe.u.freq.e = 6;
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_FREQ_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+
+ /* Add quality statistics */
+ iwe.cmd = IWEVQUAL;
+ /*
+ * level and noise below are mapped into an unsigned 8 bit number,
+ * ranging from [-192; 63]. The way this is achieved is simply to
+ * add 0x100 onto the number if it is negative,
+ * once clipped to the correct range.
+ */
+ signal = (s16)unifi2host_16(msi->Rssi); /* This value is in dBm */
+ /* Clip range of snr */
+ snr = (((s16)unifi2host_16(msi->Snr)) > 0) ? (s16)unifi2host_16(msi->Snr) : 0; /* In dB relative, from 0 - 255 */
+ snr = (snr < 255) ? snr : 255;
+ noise = signal - snr;
+
+ /* Clip range of signal */
+ signal = (signal < 63) ? signal : 63;
+ signal = (signal > -192) ? signal : -192;
+
+ /* Clip range of noise */
+ noise = (noise < 63) ? noise : 63;
+ noise = (noise > -192) ? noise : -192;
+
+ /* Make u8 */
+ signal = ( signal < 0 ) ? signal + 0x100 : signal;
+ noise = ( noise < 0 ) ? noise + 0x100 : noise;
+
+ iwe.u.qual.level = (u8)signal; /* -192 : 63 */
+ iwe.u.qual.noise = (u8)noise; /* -192 : 63 */
+ iwe.u.qual.qual = snr; /* 0 : 255 */
+ iwe.u.qual.updated = 0;
+#if WIRELESS_EXT > 16
+ iwe.u.qual.updated |= IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED |
+ IW_QUAL_QUAL_UPDATED;
+#if WIRELESS_EXT > 18
+ iwe.u.qual.updated |= IW_QUAL_DBM;
+#endif
+#endif
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_QUAL_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & SIG_CAP_PRIVACY) {
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ } else {
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ }
+ iwe.u.data.length = 0;
+ iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+ r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, "");
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+
+ /*
+ * Rate : stuffing multiple values in a single event require a bit
+ * more of magic - Jean II
+ */
+ current_val = start_buf + IW_EV_LCP_LEN;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ elem = unifi_find_info_element(IE_SUPPORTED_RATES_ID,
+ info_elems, info_elem_len);
+ if (elem) {
+ int e_len = elem[1];
+ const unsigned char *e_ptr = elem + 2;
+
+ /*
+ * Count how many rates we have.
+ * Zero marks the end of the list, if the list is not truncated.
+ */
+ /* Max 8 values */
+ for (i = 0; i < e_len; i++) {
+ if (e_ptr[i] == 0) {
+ break;
+ }
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ if (r < 0) {
+ return r;
+ }
+ current_val += r;
+ }
+ }
+ elem = unifi_find_info_element(IE_EXTENDED_SUPPORTED_RATES_ID,
+ info_elems, info_elem_len);
+ if (elem) {
+ int e_len = elem[1];
+ const unsigned char *e_ptr = elem + 2;
+
+ /*
+ * Count how many rates we have.
+ * Zero marks the end of the list, if the list is not truncated.
+ */
+ /* Max 8 values */
+ for (i = 0; i < e_len; i++) {
+ if (e_ptr[i] == 0) {
+ break;
+ }
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ if (r < 0) {
+ return r;
+ }
+ current_val += r;
+ }
+ }
+ /* Check if we added any rates event */
+ if ((current_val - start_buf) > IW_EV_LCP_LEN) {
+ start_buf = current_val;
+ }
+
+
+#if WIRELESS_EXT > 17
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = info_elem_len;
+
+ r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, info_elems);
+ if (r < 0) {
+ return r;
+ }
+
+ start_buf += r;
+#endif /* WE > 17 */
+
+ return (start_buf - current_ev);
+} /* unifi_translate_scan() */
+
+
+
+static int
+unifi_giwscan(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *dwrq = &wrqu->data;
+
+ char *current_ev = extra;
+ int index, r;
+
+ CHECK_INITED(priv);
+
+ LOCK_DRIVER(priv);
+
+ /* Read and parse all entries. Loop until there are no more. */
+ index = 0;
+ while (1) {
+ /* Retrieve a scan report and translate it to WE format */
+ scan_info_t *si;
+
+ si = unifi_get_scan_report(priv, index);
+ if (!si) {
+ break;
+ }
+#if 0
+ printk("type %d, mac %02x:%02x:%02x:%02x:%02x:%02x, "
+ "beacon %d, ts %lld, lt %lld,\n"
+ "chan %d, freq %d, caps 0x%X, rssi %d, snr %d\n",
+ si->msi.BssType,
+ si->msi.Bssid.x[0], si->msi.Bssid.x[1], si->msi.Bssid.x[2],
+ si->msi.Bssid.x[3], si->msi.Bssid.x[4], si->msi.Bssid.x[5],
+ si->msi.BeaconPeriod,
+ si->msi.Timestamp,
+ si->msi.LocalTime,
+ si->msi.Channel,
+ si->msi.ChannelFrequency,
+ si->msi.CapabilityInformation,
+ si->msi.Rssi,
+ si->msi.Snr);
+#endif
+
+ r = unifi_translate_scan(dev, info, current_ev, extra + dwrq->length,
+ si, index+1);
+ if (r < 0) {
+ UNLOCK_DRIVER(priv);
+ return r;
+ }
+
+ current_ev += r;
+ index++;
+ }
+
+ UNLOCK_DRIVER(priv);
+
+ /* Length of data */
+ dwrq->length = (current_ev - extra);
+ dwrq->flags = 0; /* todo */
+
+ return 0;
+} /* unifi_giwscan() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwessid
+ *
+ * Request to join a network or start and AdHoc.
+ *
+ * Arguments:
+ * dev Pointer to network device struct.
+ * info Pointer to broken-out ioctl request.
+ * data Pointer to argument data.
+ * essid Pointer to string giving name of network to join
+ * or start
+ *
+ * Returns:
+ * 0 on success and everything complete
+ * -EINPROGRESS to have the higher level call the commit method.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwessid(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ unifi_priv_t *priv = dev->priv;
+ int len;
+ int err = 0;
+
+ char *ssid;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ if (priv->wext_conf.mode == IW_MODE_MONITOR) {
+ return -EINVAL;
+ }
+
+ /* Zero out string buffer */
+ memset(priv->wext_conf.desired_ssid, 0, UNIFI_MAX_SSID_LEN);
+ ssid = NULL;
+
+ /*
+ * Bit 0 of flags indicates whether to join a particular
+ * AP (flags=1) or any AP (flags=0).
+ */
+ if (data->flags & 1) {
+ /* Limit length */
+ len = data->length;
+ if (len > UNIFI_MAX_SSID_LEN) {
+ len = UNIFI_MAX_SSID_LEN;
+ }
+
+ memcpy(priv->wext_conf.desired_ssid, essid, len);
+ ssid = priv->wext_conf.desired_ssid;
+ unifi_trace(priv, UDBG1, "siwessid: %s, len %d, flags=%#x\n",
+ priv->wext_conf.desired_ssid, len, data->flags);
+ }
+
+ /*
+ * If this flag is set we need to wait for a bssid set before
+ * attempting to join the desired network.
+ */
+ if (priv->wext_conf.disable_join_on_ssid_set == 0) {
+ /*
+ * ssid is NULL for wildcard, but could be empty string
+ * to look for a genuinely empty SSID.
+ */
+ err = unifi_autojoin(priv, ssid);
+ } else {
+ /*
+ * If the flag was set, we clear it and wait a new set, of either
+ * ssid or bssid. Normaly this flag was set by the wpa_supplicant
+ * and the next step will be a call to SIOCSIWAP handler.
+ * See more info in SIOCSIWGENIE handler.
+ */
+ priv->wext_conf.disable_join_on_ssid_set = 0;
+ }
+
+ func_exit();
+ return err;
+} /* unifi_siwessid() */
+
+
+
+static int
+unifi_giwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *essid)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *data = &wrqu->essid;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ if (priv->wext_conf.flag_associated) {
+ data->length = strlen(priv->wext_conf.current_ssid);
+ strncpy(essid, priv->wext_conf.current_ssid, data->length);
+ data->flags = 1; /* active */
+ }
+
+ unifi_trace(priv, UDBG2, "unifi_giwessid: %.*s\n", data->length, essid);
+
+ func_exit();
+ return 0;
+} /* unifi_giwessid() */
+
+
+
+static int
+unifi_siwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_param *args = &wrqu->bitrate;
+ int rate, flag;
+ int r;
+
+ CHECK_INITED(priv);
+
+ /*
+ * If args->fixed == 0, value is max rate or -1 for best
+ * If args->fixed == 1, value is rate to set or -1 for best
+ * args->disabled and args->flags are not used in SIOCSIWRATE
+ */
+
+ /* Default to auto rate algorithm */
+ rate = 0; /* in 500Kbit/s, 0 means auto */
+ flag = 1; /* 1 means rate is a maximum, 2 means rate is a set value */
+
+ if (args->fixed == 1) {
+ flag = 2;
+ }
+ if (args->value != -1) {
+ rate = args->value / 500000;
+ }
+
+ r = unifi_set_mib_int(priv, priv->wext_client, unifiFixTxDataRate, rate);
+ if (r == 0) {
+ r = unifi_set_mib_int(priv, priv->wext_client, unifiFixMaxTxDataRate, flag);
+ }
+ if (r < 0) {
+ return -EIO;
+ }
+ if (r > 0) {
+ return -EINVAL;
+ }
+
+ return 0;
+} /* unifi_siwrate() */
+
+
+static int
+unifi_giwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_param *args = &wrqu->bitrate;
+ int r;
+ int bitrate, flag;
+
+ CHECK_INITED(priv);
+
+ flag = 0;
+ bitrate = 0;
+
+ r = unifi_get_mib_int(priv, priv->wext_client, unifiTxDataRate, &bitrate);
+ if (r == 0) {
+ r = unifi_get_mib_int(priv, priv->wext_client, unifiFixMaxTxDataRate, &flag);
+ if (r == 1) {
+ /* MIB not present, not fatal */
+ r = 0;
+ }
+ }
+
+ if (r < 0) {
+ return -EIO;
+ }
+ if (r > 0) {
+ return -EINVAL;
+ }
+
+ args->value = bitrate * 500000;
+ args->fixed = (flag == 2) ? 1 : 0;
+
+ return 0;
+} /* unifi_giwrate() */
+
+static int
+unifi_siwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int val = wrqu->rts.value;
+ int ret = 0;
+
+ CHECK_INITED(priv);
+
+ unifi_trace(priv, UDBG2, "Set RTS from %d to %d (dis: %d)\n",
+ priv->wext_conf.rts_thresh, val, wrqu->rts.disabled);
+
+ if (wrqu->rts.disabled) {
+ val = 2347;
+ }
+
+ if ( (val < 0) || (val > 2347) )
+ {
+ return -EINVAL;
+ }
+
+ ret = set_rts_threshold(priv, val);
+
+ return ret;
+}
+
+static int
+unifi_giwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r;
+ int rts_thresh;
+ char oidstr[128];
+
+ CHECK_INITED(priv);
+
+ /* Build the OID string by appending the if_index */
+ snprintf(oidstr, 128, "%s.%d", dot11RTSThreshold, priv->if_index);
+
+ r = unifi_get_mib_int(priv, priv->wext_client, oidstr, &rts_thresh);
+ if (r < 0) {
+ return -EIO;
+ }
+ if (r > 0) {
+ return -EINVAL;
+ }
+
+ if (rts_thresh > 2347) {
+ rts_thresh = 2347;
+ }
+
+ wrqu->rts.value = rts_thresh;
+ wrqu->rts.disabled = (rts_thresh == 2347);
+ wrqu->rts.fixed = 1;
+
+ return 0;
+}
+
+static int
+unifi_siwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int val = wrqu->frag.value;
+ int r = 0;
+
+ CHECK_INITED(priv);
+
+ unifi_trace(priv, UDBG2, "Set Frag from %d to %d (dis: %d)\n",
+ priv->wext_conf.frag_thresh, val, wrqu->frag.disabled);
+
+ if (wrqu->frag.disabled)
+ val = 2346;
+
+ if ( (val < 256) || (val > 2347) )
+ return -EINVAL;
+
+ /* Fragmentation Threashold must be even */
+ r = set_fragmentation_threshold(priv, (val & ~0x1));
+
+ return 0;
+}
+
+static int
+unifi_giwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r;
+ int frag_thresh;
+ char oidstr[128];
+
+ CHECK_INITED(priv);
+
+ /* Build the OID string by appending the if_index */
+ snprintf(oidstr, 128, "%s.%d", dot11FragmentationThreshold, priv->if_index);
+ r = unifi_get_mib_int(priv, priv->wext_client, oidstr, &frag_thresh);
+ if (r < 0) {
+ return -EIO;
+ }
+ if (r > 0) {
+ return -EINVAL;
+ }
+
+ /* Sanity checks */
+ if (frag_thresh > 2346) {
+ frag_thresh = 2346;
+ } else {
+ if (frag_thresh < 256) {
+ frag_thresh = 256;
+ }
+ }
+
+ /* Build the return structure */
+ wrqu->frag.value = frag_thresh;
+ wrqu->frag.disabled = (frag_thresh == 2346);
+ wrqu->frag.fixed = 1;
+
+ return 0;
+}
+
+#if 0
+static int
+unifi_siwtxpow(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return 0;
+}
+
+
+static int
+unifi_giwtxpow(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return 0;
+}
+
+
+static int
+unifi_siwretry(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return 0;
+}
+
+
+static int
+unifi_giwretry(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return 0;
+}
+#endif
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwencode
+ *
+ * Set the privacy mode, i.e. encryption and authentication.
+ * This is only WEP and primarily for "iwconfig eth2 encode ...".
+ * WPA is handled differently, see unifi_siwencodeext.
+ *
+ * The interpretation of the arguments is somewhat convoluted:
+ * - setting a key value implies that key should be used and privacy
+ * turned on.
+ * - explicit settings override this.
+ *
+ * Arguments:
+ * dev Pointer to network device struct.
+ * info Pointer to broken-out ioctl request.
+ * wrqu Pointer to argument data.
+ * extra Pointer to any additional bulk data.
+ *
+ * Returns:
+ * 0 on success and everything complete
+ * -EINPROGRESS to have the higher level call the commit method.
+ * ---------------------------------------------------------------------------
+ */
+static int
+_unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *erq = &wrqu->encoding;
+ int index;
+ int privacy = -1;
+ int rc = 0;
+ int force_set_key_index = 0;
+
+ func_enter();
+
+ /*
+ * Key index is encoded in the flags.
+ * 0 - use current default,
+ * 1-4 - if a key value is given set that key
+ * if not use that key
+ */
+ index = (erq->flags & IW_ENCODE_INDEX); /* key number, 1-4 */
+ if ((index < 0) || (index > 4)) {
+ return -EINVAL;
+ }
+
+ /*
+ * Basic checking: do we have a key to set ?
+ * The IW_ENCODE_NOKEY flag is set when no key is present (only change flags),
+ * but older versions rely on sending a key id 1-4.
+ */
+ if (erq->length > 0) {
+ wep_key_t key;
+
+ /* Check the size of the key */
+ if ((erq->length > LARGE_KEY_SIZE) || (erq->length < SMALL_KEY_SIZE)) {
+ return -EINVAL;
+ }
+
+ /* Check the index (none (i.e. 0) means use current) */
+ if ((index < 1) || (index > 4)) {
+ /* If we do not have a previous key, use 1 as default */
+ if (!priv->wext_conf.wep_key_id) {
+ priv->wext_conf.wep_key_id = 1;
+ force_set_key_index = 1;
+ }
+ index = priv->wext_conf.wep_key_id;
+ }
+
+ /* If we didn't have a key and a valid index is set, we want to remember it*/
+ if (!priv->wext_conf.wep_key_id) {
+ priv->wext_conf.wep_key_id = index;
+ force_set_key_index = 1;
+ }
+
+ privacy = 1;
+
+ /* Set the length */
+ if (erq->length > SMALL_KEY_SIZE) {
+ key.len = LARGE_KEY_SIZE;
+ } else {
+ key.len = SMALL_KEY_SIZE;
+ }
+ /* Check if the key is not marked as invalid */
+ if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
+
+ /* Cleanup */
+ memset(key.key, 0, UNIFI_MAX_KEY_SIZE);
+
+ /* Copy the key in the driver */
+ memcpy(key.key, extra, erq->length);
+
+ /* Send the key to the card */
+ unifi_trace(priv, UDBG1, "set WEP key %d\n", index);
+ set_wep_key(priv, index, key.key, key.len);
+
+ if (force_set_key_index == 1) {
+ unifi_trace(priv, UDBG1, "set WEP key index %d\n", index - 1);
+ rc = set_default_wep_key(priv, index - 1);
+ }
+ }
+ } else {
+ /*
+ * No additional key data, so it must be a request to change the
+ * active key.
+ */
+ if (index != 0) {
+ unifi_trace(priv, UDBG1, "use WEP key %d\n", index - 1);
+
+ /* Tell UniFi which key to use */
+ rc = set_default_wep_key(priv, index - 1);
+
+ /* Remember current key id */
+ priv->wext_conf.wep_key_id = index;
+
+ /* Turn on encryption */
+ privacy = 1;
+ }
+ }
+
+
+ /* Read the flags */
+ if (erq->flags & IW_ENCODE_DISABLED) {
+ /* disable encryption */
+ unifi_trace(priv, UDBG1, "disable WEP encryption\n");
+ privacy = 0;
+ priv->wext_conf.auth_type = CSR_OPEN_SYSTEM;
+ priv->wext_conf.wep_key_id = 0;
+ }
+
+ if (erq->flags & IW_ENCODE_RESTRICTED) {
+ /* Use shared key auth */
+ unifi_trace(priv, UDBG1, "use WEP shared-key auth\n");
+ priv->wext_conf.auth_type = CSR_SHARED_KEY;
+ }
+ if (erq->flags & IW_ENCODE_OPEN) {
+ /* Only Wep */
+ unifi_trace(priv, UDBG1, "use WEP open-system auth\n");
+ priv->wext_conf.auth_type = CSR_OPEN_SYSTEM;
+ }
+
+
+ /* Commit the changes to flags if needed */
+ if (privacy != -1) {
+ unifi_trace(priv, UDBG1, "setting WEP encryption = %d\n", privacy);
+ set_privacy_invoked(priv, privacy);
+ priv->wext_conf.block_controlled_port = unifi_8021x_PortOpen;
+
+ /* Clear the WPA state. */
+#if WIRELESS_EXT > 17
+ priv->wext_conf.wpa_version = IW_AUTH_WPA_VERSION_DISABLED;
+#endif /* WIRELESS_EXT > 17 */
+ priv->wext_conf.generic_ie_len = 0;
+ }
+
+ func_exit_r(rc);
+ return rc;
+} /* _unifi_siwencode() */
+
+
+static int
+unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err;
+
+ CHECK_INITED(priv);
+
+ LOCK_DRIVER(priv);
+ err = _unifi_siwencode(dev, info, wrqu, extra);
+ /* force a rejoin if associated */
+ if (!err && priv->wext_conf.flag_associated) {
+ unifi_join_bss(priv, priv->wext_conf.current_bssid);
+ }
+ UNLOCK_DRIVER(priv);
+
+ return err;
+} /* unifi_siwencode() */
+
+static int
+unifi_giwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *erq = &wrqu->encoding;
+
+ CHECK_INITED(priv);
+
+ if (priv->wext_conf.wep_key_id == 0)
+ erq->flags = IW_ENCODE_DISABLED;
+ else {
+ int index = priv->wext_conf.wep_key_id - 1;
+ wep_key_t *key = priv->wext_conf.wep_keys + index;
+
+ if (priv->wext_conf.auth_type == CSR_SHARED_KEY)
+ erq->flags = IW_ENCODE_RESTRICTED;
+ else
+ erq->flags = IW_ENCODE_OPEN;
+
+ erq->flags |= (index & IW_ENCODE_INDEX);
+ erq->length = key->len;
+ memcpy(extra, key->key, key->len);
+ }
+
+ return 0;
+} /* unifi_giwencode() */
+
+
+static int
+unifi_siwpower(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_param *args = &wrqu->power;
+ unifi_priv_t *priv = dev->priv;
+ int pm_mode, listen_interval, wake_for_dtim;
+ int rc = 0;
+
+ CHECK_INITED(priv);
+
+ pm_mode = priv->wext_conf.power_mode;
+ listen_interval = priv->wext_conf.assoc_listen_interval;
+ wake_for_dtim = priv->wext_conf.wakeup_for_dtims;
+
+ /*
+ * If "off" is given, set mode to Active.
+ * Otherwise set mode to PowerSave.
+ * Optionally set the listen interval, but this is only
+ * used if called before associating with an AP.
+ */
+ if (args->disabled) {
+ pm_mode = CSR_PMM_ACTIVE_MODE; /* Active */
+ }
+ else
+ {
+ pm_mode = CSR_PMM_POWER_SAVE; /* PowerSave */
+
+ switch (args->flags & IW_POWER_TYPE) {
+ case 0:
+ /* not specified */
+ break;
+ case IW_POWER_PERIOD:
+ listen_interval = args->value / 1000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (args->flags & IW_POWER_MODE) {
+ case 0:
+ /* not specified */
+ break;
+ case IW_POWER_UNICAST_R:
+ /* not interested in broadcast packets */
+ wake_for_dtim = 0;
+ break;
+ case IW_POWER_ALL_R:
+ /* yes, we are interested in broadcast packets */
+ wake_for_dtim = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* Set power-saving mode if requested */
+ if ((priv->wext_conf.power_mode != pm_mode) || (priv->wext_conf.wakeup_for_dtims != wake_for_dtim)) {
+ priv->wext_conf.power_mode = pm_mode;
+ priv->wext_conf.wakeup_for_dtims = wake_for_dtim;
+
+ LOCK_DRIVER(priv);
+ rc = unifi_set_powermode(priv);
+ UNLOCK_DRIVER(priv);
+
+ /* Configure deep sleep signaling */
+ if (priv->wext_conf.power_mode || (priv->connected == UnifiNotConnected)) {
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_ENABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+ } else {
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_DISABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+ }
+ }
+
+ /* If the listen interval has changed .. */
+ if (priv->wext_conf.assoc_listen_interval != listen_interval) {
+ /* .. store the new value. */
+ priv->wext_conf.assoc_listen_interval = listen_interval;
+
+#if WIRELESS_EXT > 17
+ /*
+ * If the wpa_supplicant drives us, we can not apply the new
+ * value right now. We will use it the next time that
+ * we will send the association request.
+ */
+ if ((priv->wext_conf.wpa_version == IW_AUTH_WPA_VERSION_WPA) ||
+ (priv->wext_conf.wpa_version == IW_AUTH_WPA_VERSION_WPA2)) {
+ return rc;
+ }
+#endif /* WIRELESS_EXT > 17 */
+
+ /* If we are associated to an AP, reassociate to apply the new value. */
+ if ((priv->connected == UnifiConnected) &&
+ ((priv->wext_conf.capability & SIG_CAP_IBSS) == 0)) {
+ rc = unifi_join_bss(priv, priv->wext_conf.current_bssid);
+ }
+ }
+
+ return rc;
+} /* unifi_siwpower() */
+
+static int
+unifi_giwpower(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_param *args = &wrqu->power;
+ unifi_priv_t *priv = dev->priv;
+
+ CHECK_INITED(priv);
+
+ args->disabled = (priv->wext_conf.power_mode == 0);
+ if (args->disabled) {
+ args->flags = 0;
+ return 0;
+ }
+
+ args->flags = 0;
+ if (priv->wext_conf.wakeup_for_dtims) {
+ args->flags |= IW_POWER_ALL_R;
+ } else {
+ args->flags |= IW_POWER_UNICAST_R;
+ }
+
+ args->flags |= IW_POWER_PERIOD;
+ args->value = priv->wext_conf.assoc_listen_interval * 1000;
+
+ return 0;
+} /* unifi_giwpower() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwcommit - handler for SIOCSIWCOMMIT
+ *
+ * Apply all the parameters that have been set.
+ * In practice this means:
+ * - do a scan
+ * - join a network or start an AdHoc
+ * - authenticate and associate.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwcommit(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return 0;
+} /* unifi_siwcommit() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwmlme
+ *
+ * Handler for SIOCSIWMLME.
+ * Requests a MLME operation; uses struct iw_mlme
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+#if WIRELESS_EXT > 17
+static int
+_unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ CSR_SIGNAL signal;
+ unifi_priv_t *priv = dev->priv;
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ int timeout = 5000;
+ int r, result=0;
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ {
+ CSR_MLME_DEAUTHENTICATE_REQUEST *req = &signal.u.MlmeDeauthenticateRequest;
+
+ memcpy(&req->PeerStaAddress, mlme->addr.sa_data, ETH_ALEN);
+ req->ReasonCode = cpu_to_le16(mlme->reason_code);
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_DEAUTHENTICATE_REQUEST_ID;
+
+ r = unifi_mlme_blocking_request(priv, priv->wext_client, &signal, NULL, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send DEAUTHENTICATE request, error %d\n", r);
+ return r;
+ }
+
+ r = priv->wext_client->reply_signal->u.MlmeDeauthenticateConfirm.ResultCode;
+ if (r) {
+ unifi_notice(priv, "DEAUTHENTICATE request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ }
+
+ }
+ break;
+
+ case IW_MLME_DISASSOC:
+ {
+ CSR_MLME_DISASSOCIATE_REQUEST *req = &signal.u.MlmeDisassociateRequest;
+
+ memcpy(&req->PeerStaAddress, mlme->addr.sa_data, ETH_ALEN);
+ req->ReasonCode = cpu_to_le16(mlme->reason_code);
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_DISASSOCIATE_REQUEST_ID;
+
+ r = unifi_mlme_blocking_request(priv, priv->wext_client, &signal, NULL, timeout);
+ if (r < 0) {
+ unifi_error(priv, "failed to send DISASSOCIATE request, error %d\n", r);
+ return r;
+ }
+
+ r = priv->wext_client->reply_signal->u.MlmeDisassociateConfirm.ResultCode;
+ if (r) {
+ unifi_notice(priv, "DISASSOCIATE request was rejected with result 0x%X (%s)\n",
+ r, lookup_result_code(r));
+ }
+
+ }
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return result;
+} /* _unifi_siwmlme() */
+
+static int
+unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err;
+
+ CHECK_INITED(priv);
+
+ LOCK_DRIVER(priv);
+ err = _unifi_siwmlme(dev, info, wrqu, extra);
+ UNLOCK_DRIVER(priv);
+
+ return err;
+} /* unifi_siwmlme() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwgenie
+ * unifi_giwgenie
+ *
+ * WPA : Generic IEEE 802.11 information element (e.g., for WPA/RSN/WMM).
+ * Handlers for SIOCSIWGENIE, SIOCGIWGENIE - set/get generic IE
+ *
+ * The host program (e.g. wpa_supplicant) uses this call to set the
+ * additional IEs to accompany the next (Associate?) request.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * Notes:
+ * From wireless.h:
+ * This ioctl uses struct iw_point and data buffer that includes IE id
+ * and len fields. More than one IE may be included in the
+ * request. Setting the generic IE to empty buffer (len=0) removes the
+ * generic IE from the driver.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int len;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ len = wrqu->data.length;
+ if (len > IE_VECTOR_MAXLEN) {
+ len = IE_VECTOR_MAXLEN;
+ }
+
+ priv->wext_conf.generic_ie_len = len;
+ memcpy(priv->wext_conf.generic_ie, extra, len);
+
+ func_exit();
+ return 0;
+} /* unifi_siwgenie() */
+
+static int
+unifi_giwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int len = priv->wext_conf.generic_ie_len;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ if (len == 0) {
+ wrqu->data.length = 0;
+ return 0;
+ }
+
+ if (wrqu->data.length < len) {
+ return -E2BIG;
+ }
+
+ wrqu->data.length = len;
+ memcpy(extra, priv->wext_conf.generic_ie, len);
+
+ func_exit();
+
+ return 0;
+} /* unifi_giwgenie() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwauth
+ * unifi_giwauth
+ *
+ * Handlers for SIOCSIWAUTH, SIOCGIWAUTH
+ * Set/get various authentication parameters.
+ *
+ * Arguments:
+ *
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+_unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int ret = 0;
+
+ func_enter();
+
+ switch (wrqu->param.flags & IW_AUTH_INDEX) {
+
+ case IW_AUTH_WPA_ENABLED:
+ unifi_trace(priv, UDBG1, "IW_AUTH_WPA_ENABLED: %d\n", wrqu->param.value);
+
+ if (wrqu->param.value == 0) {
+ ret = set_rsna_enabled(priv, 0);
+ if (ret != 0) {
+ unifi_trace(priv, UDBG2, "set_rsna_enabled returned %d\n", ret);
+ ret = -EIO;
+ }
+
+ /* Clear the WPA state information. */
+ priv->wext_conf.generic_ie_len = 0;
+ priv->wext_conf.block_controlled_port = unifi_8021x_PortOpen;
+ }
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ unifi_trace(priv, UDBG1, "IW_AUTH_PRIVACY_INVOKED: %d\n", wrqu->param.value);
+ set_privacy_invoked(priv, wrqu->param.value);
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ switch (wrqu->param.value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM :
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_OPEN_SYSTEM)\n", wrqu->param.value);
+ priv->wext_conf.auth_type = CSR_OPEN_SYSTEM;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY :
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_SHARED_KEY)\n", wrqu->param.value);
+ priv->wext_conf.auth_type = CSR_SHARED_KEY;
+ break;
+ case IW_AUTH_ALG_LEAP :
+ /* Initial exchanges using open-system to set EAP */
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_LEAP)\n", wrqu->param.value);
+ priv->wext_conf.auth_type = CSR_OPEN_SYSTEM;
+ break;
+ default:
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: invalid value %d\n",
+ wrqu->param.value);
+ return -EINVAL;
+ }
+ break;
+
+ case IW_AUTH_WPA_VERSION:
+ unifi_trace(priv, UDBG1, "IW_AUTH_WPA_VERSION: %d\n", wrqu->param.value);
+ /*
+ IW_AUTH_WPA_VERSION_DISABLED 0x00000001
+ IW_AUTH_WPA_VERSION_WPA 0x00000002
+ IW_AUTH_WPA_VERSION_WPA2 0x00000004
+ */
+ priv->wext_conf.wpa_version = wrqu->param.value;
+ /* wpa_supplicant sets this ioctl prior ssid and essid set.
+ * We do not want to join to the selected ssid, until the
+ * essid is set. So we temprorarly disable the join request
+ * when the ssid is set.
+ * For more info see also SIOCSIWESSID handler.
+ */
+ priv->wext_conf.disable_join_on_ssid_set = 1;
+
+ if (wrqu->param.value & IW_AUTH_WPA_VERSION_DISABLED) {
+ ret = set_rsna_enabled(priv, 0);
+ if (ret != 0) {
+ unifi_trace(priv, UDBG2, "set_rsna_enabled returned %d\n", ret);
+ ret = -EIO;
+ }
+
+ /* Clear the WPA state information. */
+ priv->wext_conf.generic_ie_len = 0;
+ priv->wext_conf.block_controlled_port = unifi_8021x_PortOpen;
+ } else {
+ ret = set_rsna_enabled(priv, 1);
+ if (ret != 0) {
+ unifi_trace(priv, UDBG2, "set_rsna_enabled returned %d\n", ret);
+ ret = -EIO;
+ }
+ priv->wext_conf.block_controlled_port = unifi_8021x_PortClosedDiscard;
+ }
+ break;
+
+ case IW_AUTH_CIPHER_PAIRWISE:
+ unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_PAIRWISE: %d\n", wrqu->param.value);
+ /*
+ * one of:
+ IW_AUTH_CIPHER_NONE 0x00000001
+ IW_AUTH_CIPHER_WEP40 0x00000002
+ IW_AUTH_CIPHER_TKIP 0x00000004
+ IW_AUTH_CIPHER_CCMP 0x00000008
+ IW_AUTH_CIPHER_WEP104 0x00000010
+ */
+ priv->wext_conf.pairwise_cipher_used = wrqu->param.value;
+
+ break;
+
+ case IW_AUTH_CIPHER_GROUP:
+ unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_GROUP: %d\n", wrqu->param.value);
+ priv->wext_conf.group_cipher_used = wrqu->param.value;
+ /*
+ * Use the WPA version and the group cipher suite to set the permitted
+ * group key in the MIB. f/w uses this value to validate WPA and RSN IEs
+ * in the probe responses from the desired BSS(ID)
+ */
+ ret = set_rsna_config_group_cipher(priv, priv->wext_conf.wpa_version,
+ priv->wext_conf.group_cipher_used);
+ if (ret != 0) {
+ unifi_trace(priv, UDBG1, "set_rsna_config_group_cipher failed (ret=%d)\n", ret);
+ ret = -EIO;
+ }
+
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ unifi_trace(priv, UDBG1, "IW_AUTH_KEY_MGMT: %d\n", wrqu->param.value);
+ /*
+ IW_AUTH_KEY_MGMT_802_1X 1
+ IW_AUTH_KEY_MGMT_PSK 2
+ */
+ break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ /*
+ * Set to true at the start of the 60 second backup-off period
+ * following 2 MichaelMIC failures within 60s.
+ */
+ unifi_trace(priv, UDBG1, "IW_AUTH_TKIP_COUNTERMEASURES: %d\n", wrqu->param.value);
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ /*
+ * Set to true on init.
+ * Set to false just before associate if encryption will not be
+ * required.
+ *
+ * Note this is not the same as the 802.1X controlled port
+ */
+ unifi_trace(priv, UDBG1, "IW_AUTH_DROP_UNENCRYPTED: %d\n", wrqu->param.value);
+ priv->drop_unencrypted = (wrqu->param.value) ? 1 : 0;
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ /*
+ * This is set by wpa_supplicant to allow unencrypted EAPOL messages
+ * even if pairwise keys are set when not using WPA. IEEE 802.1X
+ * specifies that these frames are not encrypted, but WPA encrypts
+ * them when pairwise keys are in use.
+ * I think the UniFi f/w handles this decision for us.
+ */
+ unifi_trace(priv, UDBG1, "IW_AUTH_RX_UNENCRYPTED_EAPOL: %d\n", wrqu->param.value);
+ break;
+
+ case IW_AUTH_ROAMING_CONTROL:
+ unifi_trace(priv, UDBG1, "IW_AUTH_ROAMING_CONTROL: %d\n", wrqu->param.value);
+ break;
+
+ default:
+ unifi_trace(priv, UDBG1, "Unsupported auth param %d to 0x%X\n",
+ wrqu->param.flags & IW_AUTH_INDEX,
+ wrqu->param.value);
+ return -EOPNOTSUPP;
+ }
+
+ func_exit();
+
+ return ret;
+} /* _unifi_siwauth() */
+
+static int
+unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err;
+
+ CHECK_INITED(priv);
+
+ LOCK_DRIVER(priv);
+ err = _unifi_siwauth(dev, info, wrqu, extra);
+ UNLOCK_DRIVER(priv);
+
+ return err;
+} /* unifi_siwauth() */
+
+
+static int
+unifi_giwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return -EOPNOTSUPP;
+} /* unifi_giwauth() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwencodeext
+ * unifi_giwencodeext
+ *
+ * Handlers for SIOCSIWENCODEEXT, SIOCGIWENCODEEXT - set/get
+ * encoding token & mode
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * For WPA/WPA2 we don't take note of the IW_ENCODE_EXT_SET_TX_KEY flag.
+ * This flag means "use this key to encode transmissions"; we just
+ * assume only one key will be set and that is the one to use.
+ * ---------------------------------------------------------------------------
+ */
+static int
+_unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_DELETEKEYS_REQUEST *req = &signal.u.MlmeDeletekeysRequest;
+ unifi_priv_t *priv = dev->priv;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int timeout = 1000;
+ int r, rc;
+ CSR_KEY_TYPE key_type;
+ unsigned char *keydata;
+ unsigned char tkip_key[32];
+ int keyid;
+ unsigned char *a = (unsigned char *)ext->addr.sa_data;
+
+ func_enter();
+
+ unifi_trace(priv, UDBG3, "siwencodeext: flags=0x%X, alg=%d, ext_flags=0x%X, key_len=%d,\n",
+ wrqu->encoding.flags, ext->alg, ext->ext_flags, ext->key_len);
+ unifi_trace(priv, UDBG3, " addr=%02X:%02X:%02X:%02X:%02X:%02X\n",
+ a[0], a[1], a[2], a[3], a[4], a[5]);
+
+ if ((ext->key_len == 0) && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
+ /* This means use a different key (given by key_idx) for Tx. */
+ /* NYI */
+ unifi_trace(priv, UDBG1, KERN_ERR "unifi_siwencodeext: NYI should change tx key id here!!\n");
+ return -ENOTSUPP;
+ }
+
+ keydata = (unsigned char *)(ext + 1);
+ keyid = (wrqu->encoding.flags & IW_ENCODE_INDEX) - 1;
+
+ /*
+ * Check for request to delete keys for an address.
+ */
+ /* Pick out request for no privacy. */
+ if (ext->alg == IW_ENCODE_ALG_NONE) {
+
+ unifi_trace(priv, UDBG1, "Deleting %s key %d\n",
+ (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ? "GROUP" : "PAIRWISE",
+ keyid+1);
+
+ req->KeyId = keyid;
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ req->KeyType = CSR_GROUP;
+ } else {
+ req->KeyType = CSR_PAIRWISE; /* Pairwise Key */
+ }
+ memcpy(&req->Address, ext->addr.sa_data, ETH_ALEN);
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_DELETEKEYS_REQUEST_ID;
+
+ /* Queue request to UniFi and wait for confirm. */
+ r = unifi_mlme_blocking_request(priv, priv->wext_client, &signal, NULL, timeout);
+ if (r) {
+ unifi_error(priv, "failed to send DELETEKEYS request, error %d\n", r);
+ return r;
+ }
+
+ rc = priv->wext_client->reply_signal->u.MlmeDeletekeysConfirm.ResultCode;
+ if (rc) {
+ unifi_notice(priv, "DELETEKEYS request was rejected with result 0x%X (%s)\n",
+ rc, lookup_result_code(rc));
+ return -EIO;
+ }
+
+ priv->wext_conf.generic_ie_len = 0;
+
+ return 0;
+ }
+
+
+ /*
+ * Request is to set a key, not delete
+ */
+
+ /* Pick out WEP and use set_wep_key(). */
+ if (ext->alg == IW_ENCODE_ALG_WEP) {
+ /* WEP-40, WEP-104 */
+
+ /* Check for valid key length */
+ if (!((ext->key_len == 5) || (ext->key_len == 13))) {
+ unifi_trace(priv, UDBG1, KERN_ERR "Invalid length for WEP key: %d\n", ext->key_len);
+ return -EINVAL;
+ }
+
+ unifi_trace(priv, UDBG1, "Setting WEP key %d\n", keyid+1);
+ r = set_wep_key(priv, keyid+1, keydata, ext->key_len);
+ if (r) {
+ return r;
+ }
+
+ /* IW_ENCODE_EXT_SET_TX_KEY means use this key */
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ unifi_trace(priv, UDBG1, "Setting WEP key %d as default\n", keyid+1);
+ r = set_default_wep_key(priv, keyid);
+ if (r) {
+ return r;
+ }
+ /* Remember current key id */
+ priv->wext_conf.wep_key_id = keyid;
+ }
+
+ return 0;
+ }
+
+ /*
+ *
+ * If we reach here, we are dealing with a WPA/WPA2 key
+ *
+ */
+ /*
+ * TKIP keys from wpa_supplicant need swapping.
+ * What about other supplicants (when they come along)?
+ */
+ if ((ext->alg == IW_ENCODE_ALG_TKIP) && (ext->key_len == 32)) {
+ memcpy(tkip_key, keydata, 16);
+ memcpy(tkip_key + 16, keydata + 24, 8);
+ memcpy(tkip_key + 24, keydata + 16, 8);
+ keydata = tkip_key;
+ }
+
+ key_type = (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ?
+ CSR_GROUP : /* Group Key */
+ CSR_PAIRWISE; /* Pairwise Key */
+
+ r = set_rsn_key(priv, ext->addr.sa_data, ext->alg,
+ keyid, keydata, ext->key_len, key_type,
+ ((ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) ?
+ ext->rx_seq : NULL));
+ if (r) {
+ return r;
+ }
+
+
+ /*
+ * Set protection
+ */
+ r = mlme_set_protection(priv, ext->addr.sa_data, CSR_PT_RX_TX, key_type);
+ if (r) {
+ return r;
+ }
+
+ /*
+ * If this was the GROUP key, we have completed the key exchange and
+ * can open the 802.1X controlled port.
+ */
+ if (key_type == CSR_GROUP) {
+ priv->wext_conf.block_controlled_port = unifi_8021x_PortOpen;
+ }
+
+
+ func_exit();
+ return 0;
+} /* _unifi_siwencodeext() */
+
+static int
+unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err;
+
+ CHECK_INITED(priv);
+
+ LOCK_DRIVER(priv);
+ err = _unifi_siwencodeext(dev, info, wrqu, extra);
+ UNLOCK_DRIVER(priv);
+
+ return err;
+} /* unifi_siwencodeext() */
+
+
+static int
+unifi_giwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return -EOPNOTSUPP;
+} /* unifi_giwencodeext() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwpmksa
+ *
+ * SIOCSIWPMKSA - PMKSA cache operation
+ * The caller passes a pmksa structure:
+ * - cmd one of ADD, REMOVE, FLUSH
+ * - bssid MAC address
+ * - pmkid ID string (16 bytes)
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * This is not needed since we provide a siwgenie method.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwpmksa(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
+
+ unifi_trace(dev->priv, UDBG1, "SIWPMKSA: cmd %d, %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pmksa->cmd,
+ pmksa->bssid.sa_data[0],
+ pmksa->bssid.sa_data[1],
+ pmksa->bssid.sa_data[2],
+ pmksa->bssid.sa_data[3],
+ pmksa->bssid.sa_data[4],
+ pmksa->bssid.sa_data[5]);
+
+ return -EOPNOTSUPP;
+} /* unifi_siwpmksa() */
+
+#endif /* WIRELESS_EXT > 17 */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_get_wireless_stats
+ *
+ * get_wireless_stats method for Linux wireless extensions.
+ *
+ * Arguments:
+ * dev Pointer to associated netdevice.
+ *
+ * Returns:
+ * Pointer to iw_statistics struct.
+ * ---------------------------------------------------------------------------
+ */
+struct iw_statistics *
+unifi_get_wireless_stats(struct net_device *dev)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ if (priv->init_progress != UNIFI_INIT_COMPLETED) {
+ return NULL;
+ }
+
+ return &priv->wext_conf.wireless_stats;
+} /* unifi_get_wireless_stats() */
+
+
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+static const struct iw_priv_args unifi_private_args[] = {
+/*{ cmd, set_args, get_args, name } */
+ { SIOCIWS80211POWERSAVEPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_NONE, "iwprivs80211ps" },
+ { SIOCIWG80211POWERSAVEPRIV, IW_PRIV_TYPE_NONE,
+ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IWPRIV_POWER_SAVE_MAX_STRING, "iwprivg80211ps" },
+};
+
+static const iw_handler unifi_handler[] =
+{
+ (iw_handler) unifi_siwcommit, /* SIOCSIWCOMMIT */
+ (iw_handler) unifi_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) unifi_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) unifi_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) unifi_siwmode, /* SIOCSIWMODE */
+ (iw_handler) unifi_giwmode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL, /* SIOCSIWRANGE */
+ (iw_handler) unifi_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) NULL, /* SIOCSIWPRIV */
+ (iw_handler) NULL, /* SIOCGIWPRIV */
+ (iw_handler) NULL, /* SIOCSIWSTATS */
+ (iw_handler) NULL, /* SIOCGIWSTATS */
+#if 0
+ iw_handler_set_spy, /* SIOCSIWSPY */
+ iw_handler_get_spy, /* SIOCGIWSPY */
+ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
+ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
+#else
+ (iw_handler) NULL, /* SIOCSIWSPY */
+ (iw_handler) NULL, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* SIOCSIWTHRSPY */
+ (iw_handler) NULL, /* SIOCGIWTHRSPY */
+#endif
+ (iw_handler) unifi_siwap, /* SIOCSIWAP */
+ (iw_handler) unifi_giwap, /* SIOCGIWAP */
+#if WIRELESS_EXT > 17
+ /* WPA : IEEE 802.11 MLME requests */
+ unifi_siwmlme, /* SIOCSIWMLME, request MLME operation */
+#else
+ (iw_handler) NULL, /* -- hole -- */
+#endif
+ (iw_handler) NULL, /* SIOCGIWAPLIST */
+ (iw_handler) unifi_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) unifi_giwscan, /* SIOCGIWSCAN */
+ (iw_handler) unifi_siwessid, /* SIOCSIWESSID */
+ (iw_handler) unifi_giwessid, /* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) NULL, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ unifi_siwrate, /* SIOCSIWRATE */
+ unifi_giwrate, /* SIOCGIWRATE */
+ unifi_siwrts, /* SIOCSIWRTS */
+ unifi_giwrts, /* SIOCGIWRTS */
+ unifi_siwfrag, /* SIOCSIWFRAG */
+ unifi_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) NULL, /* SIOCSIWTXPOW */
+ (iw_handler) NULL, /* SIOCGIWTXPOW */
+ (iw_handler) NULL, /* SIOCSIWRETRY */
+ (iw_handler) NULL, /* SIOCGIWRETRY */
+ unifi_siwencode, /* SIOCSIWENCODE */
+ unifi_giwencode, /* SIOCGIWENCODE */
+ unifi_siwpower, /* SIOCSIWPOWER */
+ unifi_giwpower, /* SIOCGIWPOWER */
+#if WIRELESS_EXT > 17
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+
+ /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). */
+ unifi_siwgenie, /* SIOCSIWGENIE */ /* set generic IE */
+ unifi_giwgenie, /* SIOCGIWGENIE */ /* get generic IE */
+
+ /* WPA : Authentication mode parameters */
+ unifi_siwauth, /* SIOCSIWAUTH */ /* set authentication mode params */
+ unifi_giwauth, /* SIOCGIWAUTH */ /* get authentication mode params */
+
+ /* WPA : Extended version of encoding configuration */
+ unifi_siwencodeext, /* SIOCSIWENCODEEXT */ /* set encoding token & mode */
+ unifi_giwencodeext, /* SIOCGIWENCODEEXT */ /* get encoding token & mode */
+
+ /* WPA2 : PMKSA cache management */
+ unifi_siwpmksa, /* SIOCSIWPMKSA */ /* PMKSA cache operation */
+ (iw_handler) NULL, /* -- hole -- */
+#endif /* WIRELESS_EXT > 17 */
+};
+
+
+static const iw_handler unifi_private_handler[] =
+{
+ iwprivs80211ps,
+ iwprivg80211ps,
+};
+
+struct iw_handler_def unifi_iw_handler_def =
+{
+ .num_standard = sizeof(unifi_handler) / sizeof(iw_handler),
+ .num_private = sizeof(unifi_private_handler) / sizeof(iw_handler),
+ .num_private_args = sizeof(unifi_private_args) / sizeof(struct iw_priv_args),
+ .standard = (iw_handler *) unifi_handler,
+ .private = (iw_handler *) unifi_private_handler,
+ .private_args = (struct iw_priv_args *) unifi_private_args,
+#if IW_HANDLER_VERSION >= 6
+ .get_wireless_stats = unifi_get_wireless_stats,
+#endif
+#if 0
+ .spy_offset = ((void *) (&((struct unifi_info *) NULL)->spy_data) -
+ (void *) NULL),
+#endif
+};
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_init_wext_interface
+ *
+ * Registers the wext client and initialises wext related parameters.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ *
+ * Returns:
+ * 0 on success, -1 on error.
+ * ---------------------------------------------------------------------------
+ */
+int uf_init_wext_interface(unifi_priv_t *priv)
+{
+ /* register wext as a client */
+ priv->wext_client = ul_register_client(priv, 0, sme_native_mlme_event_handler);
+ if (priv->wext_client == NULL) {
+ printk(KERN_ERR "Failed to register WEXT as a unifi client\n");
+ return -1;
+ }
+
+ /* Set up fallback config */
+ priv->wext_conf.channel = -1;
+ priv->wext_conf.beacon_period = 100; /* to use in starting AdHoc network */
+ priv->wext_conf.join_failure_timeout = 2000; /* in TU (1024us) */
+ priv->wext_conf.auth_failure_timeout = 2000; /* in TU (1024us) */
+ priv->wext_conf.assoc_failure_timeout = 2000; /* in TU (1024us) */
+ memset(priv->wext_conf.current_bssid, 0xFF, ETH_ALEN);
+ priv->wext_conf.disable_join_on_ssid_set = 0;
+ priv->wext_conf.bss_wmm_capabilities = 0;
+ priv->wext_conf.wmm_bss_uapsd_mask = 0x0F; /* U-APSD */
+
+ /* power save parameters, modify with "iwconfig power ..." */
+ priv->wext_conf.power_mode = 0; /* "on" or "off" */
+ priv->wext_conf.assoc_listen_interval = 10; /* "period n" */
+ priv->wext_conf.wakeup_for_dtims = 1; /* "unicast" or "all" */
+
+ priv->wext_conf.wireless_stats.qual.qual = 0;
+ priv->wext_conf.wireless_stats.qual.level = 0;
+ priv->wext_conf.wireless_stats.qual.noise = 0;
+ priv->wext_conf.wireless_stats.qual.updated = 0x70;
+
+ return 0;
+} /* uf_init_wext_interface() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_deinit_wext_interface
+ *
+ * Deregisters the wext client.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void uf_deinit_wext_interface(unifi_priv_t *priv)
+{
+ /* Unregister WEXT as a client. */
+ if (priv->wext_client) {
+ ul_deregister_client(priv->wext_client);
+ priv->wext_client = NULL;
+ }
+} /* uf_deinit_wext_interface() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * _clear_association_status
+ *
+ * Reinitialise 802.11 association related wext parameters.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+_clear_association_status(unifi_priv_t *priv)
+{
+ memset(priv->wext_conf.current_ssid, 0, UNIFI_MAX_SSID_LEN);
+ memset((void*)priv->wext_conf.current_bssid, 0, ETH_ALEN);
+ priv->wext_conf.capability = 0;
+ priv->wext_conf.flag_associated = 0;
+ if (priv->wext_conf.mode == IW_MODE_INFRA) {
+ priv->wext_conf.channel = -1;
+ }
+} /* _clear_association_status() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_connected_ind
+ *
+ * Called when a CONNECTED indication is received from UniFi.
+ *
+ * Arguments:
+ * ospriv OS private context pointer.
+ * ind Pointer to a MLME_CONNECTED_INDICATION struct.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * The connect indication from UniFi is used to configure the
+ * network device status of the driver.
+ * ---------------------------------------------------------------------------
+ */
+static void
+unifi_connected_ind(unifi_priv_t *priv, const CSR_MLME_CONNECTED_INDICATION *ind)
+{
+ struct net_device *dev = priv->netdev;
+ func_enter();
+
+ TIME_MARK("UniFi connected");
+ unifi_trace(priv, UDBG2, "ConnectionStatus = %d\n", ind->ConnectionStatus);
+
+ if (priv->netdev_registered) {
+ /* Report using device name when we have registered the net device. */
+ unifi_notice(priv, "%s: link is %s\n",
+ dev->name,
+ (ind->ConnectionStatus) ? "up" : "down");
+ } else {
+ unifi_notice(priv, "unifi%d: link is %s\n",
+ priv->instance,
+ (ind->ConnectionStatus) ? "up" : "down");
+ }
+
+ if (ind->ConnectionStatus) {
+ netif_carrier_on(dev);
+ UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev);
+ priv->connected = UnifiConnected;
+
+ /*
+ * Send wireless-extension event up to userland to announce
+ * connection to an IBSS.
+ */
+ if ((priv->wext_conf.capability & SIG_CAP_IBSS) == SIG_CAP_IBSS) {
+ wext_send_assoc_event(priv, priv->wext_conf.current_bssid,
+ NULL, 0, NULL, 0, NULL, 0);
+ priv->wext_conf.flag_associated = 1;
+ }
+
+ /*
+ * If the power save mode is active, we should disable
+ * the deep sleep signaling, to avoid the overhead.
+ */
+ if (priv->wext_conf.power_mode == 0) {
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_DISABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+ }
+
+ } else {
+ netif_carrier_off(dev);
+ priv->connected = UnifiNotConnected;
+
+ /*
+ * Send wireless-extension event up to userland to announce
+ * connection lost to a BSS.
+ */
+ wext_send_disassoc_event(priv);
+ priv->wext_conf.flag_associated = 0;
+
+ /*
+ * Enable the deep sleep signaling.
+ */
+ unifi_configure_low_power_mode(priv->card,
+ UNIFI_LOW_POWER_ENABLED,
+ UNIFI_PERIODIC_WAKE_HOST_DISABLED);
+
+ }
+
+ func_exit();
+} /* unifi_connected_ind() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * sme_native_mlme_event_handler
+ *
+ * Callback function to be used as the udi_event_callback when registering
+ * as a client.
+ * This function implements a blocking request-reply interface for WEXT.
+ * To use it, a client specifies this function as the udi_event_callback
+ * to ul_register_client(). The signal dispatcher in
+ * unifi_receive_event() will call this function to deliver a signal.
+ *
+ * Arguments:
+ * pcli Pointer to the client instance.
+ * signal Pointer to the received signal.
+ * signal_len Size of the signal structure in bytes.
+ * bulkdata Pointer to structure containing any associated bulk data.
+ * dir Direction of the signal. Zero means from host,
+ * non-zero means to host.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+sme_native_mlme_event_handler(ul_client_t *pcli,
+ u8 *sig_packed, int sig_len,
+ const bulk_data_param_t *bulkdata,
+ int dir)
+{
+ CSR_SIGNAL signal;
+ int signal_len;
+ unifi_priv_t *priv = unifi_find_instance(pcli->instance);
+ int id, r;
+
+ func_enter();
+
+ /* Just a sanity check */
+ if ((sig_packed == NULL) || (sig_len <= 0)) {
+ return;
+ }
+
+ /* Get the unpacked signal */
+ r = read_unpack_signal(sig_packed, &signal);
+ if (r == 0) {
+ signal_len = SigGetSize(&signal);
+ } else {
+ unifi_error(priv, "Received unknown or corrupted signal.\n");
+ return;
+ }
+
+ id = signal.SignalPrimitiveHeader.SignalId;
+ unifi_trace(priv, UDBG4, "wext - Process signal 0x%X %s\n", id, lookup_signal_name(id));
+
+ /*
+ * Take the appropriate action for the signal.
+ */
+ switch (id) {
+ /*
+ * Confirm replies from UniFi.
+ * These all have zero or one CSR_DATAREF member.
+ */
+ case CSR_MLME_SET_CONFIRM_ID:
+ case CSR_MLME_GET_CONFIRM_ID:
+ case CSR_MLME_GET_NEXT_CONFIRM_ID:
+ case CSR_MLME_SCAN_CONFIRM_ID:
+ case CSR_MLME_JOIN_CONFIRM_ID:
+ case CSR_MLME_POWERMGT_CONFIRM_ID:
+ case CSR_MLME_DEAUTHENTICATE_CONFIRM_ID:
+ case CSR_MLME_DISASSOCIATE_CONFIRM_ID:
+ case CSR_MLME_RESET_CONFIRM_ID:
+ case CSR_MLME_START_CONFIRM_ID:
+ case CSR_MLME_SNIFFJOIN_CONFIRM_ID:
+ case CSR_MLME_AUTHENTICATE_CONFIRM_ID:
+ case CSR_MLME_ASSOCIATE_CONFIRM_ID:
+ case CSR_MLME_REASSOCIATE_CONFIRM_ID:
+ case CSR_MLME_SETKEYS_CONFIRM_ID:
+ case CSR_MLME_DELETEKEYS_CONFIRM_ID:
+ case CSR_MLME_SETPROTECTION_CONFIRM_ID:
+ case CSR_MLME_ADDTS_CONFIRM_ID:
+ unifi_mlme_copy_reply_and_wakeup_client(pcli, &signal, signal_len, bulkdata);
+ break;
+
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+#ifdef UNIFI_SNIFF_ARPHRD
+ ma_sniffdata_ind(priv,
+ &signal.u.MaSniffdataIndication,
+ bulkdata);
+#endif
+ break;
+
+ case CSR_MLME_CONNECTED_INDICATION_ID:
+ unifi_connected_ind(priv,
+ &signal.u.MlmeConnectedIndication);
+ break;
+
+ case CSR_MLME_MICHAELMICFAILURE_INDICATION_ID:
+ unifi_warning(priv, "MichaelMIC Failure: %d, %02x:%02x:%02x:%02x:%02x:%02x type %d, id %d, tsc %llu\n",
+ signal.u.MlmeMichaelmicfailureIndication.Count,
+ signal.u.MlmeMichaelmicfailureIndication.Address.x[0],
+ signal.u.MlmeMichaelmicfailureIndication.Address.x[1],
+ signal.u.MlmeMichaelmicfailureIndication.Address.x[2],
+ signal.u.MlmeMichaelmicfailureIndication.Address.x[3],
+ signal.u.MlmeMichaelmicfailureIndication.Address.x[4],
+ signal.u.MlmeMichaelmicfailureIndication.Address.x[5],
+ signal.u.MlmeMichaelmicfailureIndication.KeyType,
+ signal.u.MlmeMichaelmicfailureIndication.KeyId,
+ signal.u.MlmeMichaelmicfailureIndication.Tsc);
+
+ wext_send_michaelmicfailure_event(priv,
+ &signal.u.MlmeMichaelmicfailureIndication);
+ break;
+
+ case CSR_MLME_DEAUTHENTICATE_INDICATION_ID:
+ unifi_info(priv, "deauthenticated by AP %02X:%02X:%02X:%02X:%02X:%02X with reason %d (%s)\n",
+ signal.u.MlmeDeauthenticateIndication.PeerStaAddress.x[0],
+ signal.u.MlmeDeauthenticateIndication.PeerStaAddress.x[1],
+ signal.u.MlmeDeauthenticateIndication.PeerStaAddress.x[2],
+ signal.u.MlmeDeauthenticateIndication.PeerStaAddress.x[3],
+ signal.u.MlmeDeauthenticateIndication.PeerStaAddress.x[4],
+ signal.u.MlmeDeauthenticateIndication.PeerStaAddress.x[5],
+ signal.u.MlmeDeauthenticateIndication.ReasonCode,
+ lookup_reason_code(signal.u.MlmeDeauthenticateIndication.ReasonCode));
+
+ _clear_association_status(priv);
+ wext_send_disassoc_event(priv);
+ break;
+
+ case CSR_MLME_DISASSOCIATE_INDICATION_ID:
+ unifi_info(priv, "disassociated by AP %02X:%02X:%02X:%02X:%02X:%02X with reason %d (%s)\n",
+ signal.u.MlmeDisassociateIndication.PeerStaAddress.x[0],
+ signal.u.MlmeDisassociateIndication.PeerStaAddress.x[1],
+ signal.u.MlmeDisassociateIndication.PeerStaAddress.x[2],
+ signal.u.MlmeDisassociateIndication.PeerStaAddress.x[3],
+ signal.u.MlmeDisassociateIndication.PeerStaAddress.x[4],
+ signal.u.MlmeDisassociateIndication.PeerStaAddress.x[5],
+ signal.u.MlmeDisassociateIndication.ReasonCode,
+ lookup_reason_code(signal.u.MlmeDisassociateIndication.ReasonCode));
+
+ _clear_association_status(priv);
+ wext_send_disassoc_event(priv);
+ break;
+
+
+ case CSR_MLME_SCAN_INDICATION_ID:
+ unifi_scan_indication_handler(priv,
+ &signal.u.MlmeScanIndication,
+ bulkdata->d[0].os_data_ptr,
+ bulkdata->d[0].data_length);
+ break;
+
+ default:
+ break;
+ }
+
+ func_exit();
+} /* sme_native_mlme_event_handler() */
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_osa.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_osa.c
new file mode 100644
index 0000000..25e1db3
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_osa.c
@@ -0,0 +1,168 @@
+/** @file osa.c
+ *
+ * Operating System Abstraction main source file
+ *
+ * Copyright (C) Cambridge Silicon Radio Ltd 2007-2008. All rights reserved.
+ *
+ * @section DESCRIPTION
+ * Provides abstraction API implementation for typical OS-related functions
+ * such as malloc, free, etc.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ ****************************************************************************/
+
+/** @{
+ * @ingroup abstractions
+ */
+
+/* STANDARD INCLUDES ********************************************************/
+
+/* PROJECT INCLUDES *********************************************************/
+#include "abstractions/osa.h"
+#include "sme_trace/sme_trace.h"
+
+/* Trace may be dangerous - only enable if sme_trace doesn't use osa_ calls */
+/* #undef SME_TRACE_ENABLE */
+
+/* MACROS *******************************************************************/
+
+/* GLOBAL VARIABLE DEFINITIONS **********************************************/
+
+/* PRIVATE TYPES DEFINITIONS ************************************************/
+struct OsaMutex {
+ struct semaphore mutex;
+};
+
+/* PRIVATE CONSTANT DEFINITIONS *********************************************/
+
+/* PRIVATE VARIABLE DEFINITIONS *********************************************/
+
+/* PRIVATE FUNCTION PROTOTYPES **********************************************/
+
+/* PRIVATE FUNCTION DEFINITIONS *********************************************/
+
+/* PUBLIC FUNCTION DEFINITIONS **********************************************/
+
+void osa_initialise()
+{
+}
+
+void osa_shutdown()
+{
+}
+
+/* --------------------------------------------------------------------------
+ * Initialise the mutex so that it can be used to lock
+ * areas of code
+ */
+OsaMutex* osa_critical_section_create(void)
+{
+ OsaMutex* osaMutex = (OsaMutex*)osa_malloc(sizeof(OsaMutex));
+ init_MUTEX(&osaMutex->mutex);
+ return osaMutex;
+}
+
+/* --------------------------------------------------------------------------
+ * Destroys the mutex so that the associate resources are freed
+ */
+void osa_critical_section_destroy(OsaMutex* osaMutex)
+{
+ osa_free(osaMutex);
+}
+
+
+/* --------------------------------------------------------------------------
+ * Marks the code following this function as critical. This means no other
+ * context that uses the same critical section handle may execute the code
+ */
+void osa_critical_section_entry(OsaMutex* osaMutex)
+{
+ down_interruptible(&osaMutex->mutex);
+}
+
+
+/* --------------------------------------------------------------------------
+ * Marks the end of the critical section - many execution contexts may
+ * execute the code after this call.
+ */
+void osa_critical_section_exit(OsaMutex* osaMutex)
+{
+ up(&osaMutex->mutex);
+}
+
+/* --------------------------------------------------------------------------
+ * Return time of day in milliseconds
+ */
+uint32 osa_get_time_of_day_milli_seconds()
+{
+ uint32 timeMilliseconds;
+ timeMilliseconds = jiffies_to_msecs(jiffies);
+
+ return timeMilliseconds;
+}
+
+/* --------------------------------------------------------------------------
+ * Cause an abnormal termination of the program - verbose version
+ */
+void osa_panic_verbose(const char * fileName,
+ int lineNum,
+ osa_panic_code reason)
+{
+ sme_trace_crit((TR_OSA, "System panic in %s line %d - code %d",
+ fileName, lineNum, reason));
+ WARN_ON(1);
+}
+
+/* --------------------------------------------------------------------------
+ * Cause an abnormal termination of the program - verbose version
+ */
+void osa_panic_brief(osa_panic_code reason)
+{
+ sme_trace_crit((TR_OSA, "System panic - code %d", reason));
+ WARN_ON(1);
+}
+
+#define BYTES_FOR_SIZE_STORAGE 4
+
+void *sme_osa_malloc(unsigned int sz)
+{
+ uint8 *p_alloc;
+
+ p_alloc = (uint8*)kmalloc(sz, GFP_KERNEL);
+ if (p_alloc == NULL) {
+ sme_trace_crit((TR_OSA, "\n*** osa_malloc failed ***\n\n"));
+ return NULL;
+ }
+
+ return (p_alloc);
+}
+
+
+void *sme_osa_calloc(unsigned int nmemb, unsigned int sz)
+{
+ void *p_alloc;
+
+ p_alloc = kmalloc(nmemb * sz, GFP_KERNEL);
+ if (p_alloc == NULL) {
+ return NULL;
+ }
+ memset(p_alloc, 0, nmemb * sz);
+
+ return p_alloc;
+}
+
+
+void sme_osa_free(void *ptr)
+{
+ if (!ptr) {
+ return;
+ }
+
+ kfree(ptr);
+}
+
+
+/** @}
+ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_sys.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_sys.c
new file mode 100644
index 0000000..7d5a35c
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_sys.c
@@ -0,0 +1,652 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: sme_sys.c
+ *
+ * PURPOSE:
+ * Driver specific implementation of the SME SYS SAP.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#include "driver/unifiversion.h"
+#include "unifi_priv.h"
+
+
+/*
+ * This file implements the SME SYS API. It contains the following functions:
+ * unifi_sys_media_status_req()
+ * unifi_sys_hip_req()
+ * unifi_sys_port_configure_req()
+ * unifi_sys_wifi_on_req()
+ * unifi_sys_wifi_off_req()
+ * unifi_sys_suspend_rsp()
+ * unifi_sys_resume_rsp()
+ * unifi_sys_qos_control_req()
+ * unifi_sys_configure_power_mode_req()
+ * unifi_sys_wifi_on_rsp()
+ * unifi_sys_wifi_off_rsp()
+ * unifi_sys_multicast_address_rsp()
+ * unifi_sys_traffic_config_req()
+ * unifi_sys_traffic_classification_req()
+ * unifi_sys_tclas_add_req()
+ * unifi_sys_tclas_del_req()
+ */
+
+/*
+ * Handling the suspend and resume system events, we need to block
+ * until the SME sends the response to our indication.
+ * We use the sme_init_request() and sme_wait_for_reply()
+ * to implement this behavior in the following functions:
+ * sme_sys_suspend()
+ * sme_sys_resume()
+ */
+
+
+void unifi_sys_media_status_req(void* drvpriv, unifi_MediaStatus mediaStatus)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "unifi_sys_media_status_req: invalid smepriv\n");
+ return;
+ }
+
+ if (mediaStatus == unifi_MediaConnected) {
+ unifi_sys_ip_configured_ind(priv->smepriv, (priv->sta_ip_address != 0xFFFFFFFF));
+
+ netif_carrier_on(priv->netdev);
+ UF_NETIF_TX_WAKE_ALL_QUEUES(priv->netdev);
+
+ priv->connected = UnifiConnected;
+ } else {
+ netif_carrier_off(priv->netdev);
+ priv->connected = UnifiNotConnected;
+ }
+}
+
+
+void unifi_sys_hip_req(void* drvpriv, const unifi_DataBlock* mlmeCommand,
+ const unifi_DataBlock* dataRef1,
+ const unifi_DataBlock* dataRef2)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ bulk_data_param_t bulkdata;
+ u8 *signal_ptr;
+ int signal_length;
+ int r;
+ void *dest;
+
+ if (priv == NULL) {
+ return;
+ }
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "unifi_sys_hip_req: invalid smepriv\n");
+ return;
+ }
+
+ unifi_trace(priv, UDBG4, "unifi_sys_hip_req: 0x04%X ---->\n",
+ *((uint16*)mlmeCommand->data));
+
+ /* Construct the signal. */
+ signal_ptr = (u8*)mlmeCommand->data;
+ signal_length = mlmeCommand->length;
+
+ /*
+ * The MSB of the sender ID needs to be set to the client ID.
+ * The LSB is controlled by the SME.
+ */
+ signal_ptr[5] = (priv->sme_cli->sender_id >> 8) & 0xff;
+
+ /* Allocate buffers for the bulk data. */
+ if (dataRef1->length) {
+ r = unifi_net_data_malloc(priv, &bulkdata.d[0], dataRef1->length);
+ if (r == 0) {
+ dest = (void*)bulkdata.d[0].os_data_ptr;
+ memcpy(dest, dataRef1->data, dataRef1->length);
+ bulkdata.d[0].data_length = dataRef1->length;
+ } else {
+ }
+ } else {
+ bulkdata.d[0].data_length = 0;
+ }
+ if (dataRef2->length) {
+ r = unifi_net_data_malloc(priv, &bulkdata.d[1], dataRef2->length);
+ if (r == 0) {
+ dest = (void*)bulkdata.d[1].os_data_ptr;
+ memcpy(dest, dataRef2->data, dataRef2->length);
+ bulkdata.d[1].data_length = dataRef2->length;
+ } else {
+ }
+ } else {
+ bulkdata.d[1].data_length = 0;
+ }
+
+ unifi_trace(priv, UDBG3, "SME SEND: Signal %s \n",
+ lookup_signal_name(*((uint16*)signal_ptr)));
+
+ r = ul_send_signal_raw(priv, (const unsigned char*)signal_ptr,
+ signal_length, &bulkdata);
+ if (r) {
+ unifi_error(priv, "unifi_sys_hip_req: Failed to send signal\n");
+ /* FIXME: If r==NOCARD then ind unifi_Control_Exit */
+ unifi_sys_wifi_off_ind(priv->smepriv, unifi_Control_Error);
+ }
+
+ unifi_trace(priv, UDBG4, "unifi_sys_hip_req: <----\n");
+}
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * configure_controlled_port
+ *
+ * Store the new controlled port configuration.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * port_cfg Pointer to the controlled port configuration
+ *
+ * Returns:
+ * An unifi_ControlledPortAction value.
+ * ---------------------------------------------------------------------------
+ */
+static int
+configure_controlled_port(unifi_priv_t *priv, const unifi_controlled_port_cfg *port_cfg)
+{
+ const unsigned char broadcast_mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+ /*
+ * If the new configuration has the broadcast MAC address
+ * we invalidate all entries in the list and store the new
+ * configuration in index 0.
+ */
+ if (memcmp(port_cfg->mac_address, broadcast_mac_address, ETH_ALEN) == 0) {
+
+ memcpy((void*)(&priv->controlled_port_cfg.port_cfg[0]),
+ (void*)port_cfg, sizeof(unifi_controlled_port_cfg));
+ priv->controlled_port_cfg.entries_in_use = 1;
+ priv->controlled_port_cfg.overide_action = CONTROLLED_PORT_OVERIDE;
+
+ if (port_cfg->port_action == unifi_8021x_PortOpen) {
+ unifi_trace(priv, UDBG1, "Controlled port broadcast set to open.\n");
+
+ /*
+ * Ask stack to schedule for transmission any packets queued
+ * while controlled port was not open.
+ * Use netif_schedule() instead of netif_wake_queue() because
+ * transmission should be already enabled at this point. If it
+ * is not, probably the interface is down and should remain as is.
+ */
+ uf_resume_xmit(priv);
+ } else {
+ unifi_trace(priv, UDBG1, "Controlled port broadcast set to %s.\n",
+ (port_cfg->port_action == unifi_8021x_PortClosedDiscard) ? "discard": "closed");
+ }
+ } else {
+ /*
+ * If the new configuration is for Ad-Hoc we clear the overide action,
+ * find the first available index and store the new configuration.
+ */
+ if (priv->controlled_port_cfg.entries_in_use < UNIFI_MAX_CONNECTIONS) {
+ unifi_controlled_port_cfg *next_port_cfg;
+ /* If the broadcast configuration is still set, reset it. */
+ if (priv->controlled_port_cfg.overide_action == CONTROLLED_PORT_OVERIDE) {
+ priv->controlled_port_cfg.entries_in_use = 0;
+ priv->controlled_port_cfg.overide_action = CONTROLLED_PORT_NOT_OVERIDE;
+ }
+ /* Use the next available index. */
+ next_port_cfg = &priv->controlled_port_cfg.port_cfg[priv->controlled_port_cfg.entries_in_use];
+ memcpy((void*)next_port_cfg, (void*)port_cfg,
+ sizeof(unifi_controlled_port_cfg));
+ priv->controlled_port_cfg.entries_in_use ++;
+
+ if (next_port_cfg->port_action == unifi_8021x_PortOpen) {
+ /*
+ * Ask stack to schedule for transmission any packets queued
+ * while controlled port was not open.
+ * Use netif_schedule() instead of netif_wake_queue() because
+ * transmission should be already enabled at this point. If it
+ * is not, probably the interface is down and should remain as is.
+ */
+ uf_resume_xmit(priv);
+ }
+
+ unifi_trace(priv, UDBG1, "add a new port config (%d).\n", port_cfg->port_action);
+ } else {
+ unifi_error(priv, "controlled_port_cfg is full.\n");
+ return -EFAULT;
+ }
+ }
+ return 0;
+} /* configure_controlled_port() */
+
+
+void unifi_sys_port_configure_req(void* drvpriv,
+ unifi_PortAction uncontrolledPortAction,
+ unifi_PortAction controlledPortAction,
+ const unifi_MACAddress* macAddress)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ unifi_controlled_port_cfg controlled_port;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "unifi_sys_port_configure_req: invalid smepriv\n");
+ return;
+ }
+
+ memset(&controlled_port, 0, sizeof(unifi_controlled_port_cfg));
+ controlled_port.port_action = controlledPortAction;
+ memcpy(controlled_port.mac_address, macAddress->data, 6);
+
+ configure_controlled_port(priv, &controlled_port);
+
+ unifi_sys_port_configure_cfm(priv->smepriv, unifi_Success, macAddress);
+}
+
+
+void unifi_sys_wifi_on_req(void* drvpriv)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ unifi_Versions versions;
+ int r;
+
+ if (priv == NULL) {
+ return;
+ }
+
+ unifi_trace(priv, UDBG1, "unifi_sys_wifi_on_req\n");
+
+ /*
+ * The request to initialise UniFi might come while UniFi is running.
+ * We need to block all I/O activity until the reset completes, otherwise
+ * an SDIO error might occur resulting an indication to the SME which
+ * makes it think that the initialisation has failed.
+ */
+ priv->bh_thread.block_thread = 1;
+
+ /* Update the wifi_on state */
+ priv->wifi_on_state = wifi_on_in_progress;
+
+ r = uf_request_firmware_files(priv);
+ if (r) {
+ unifi_error(priv, "unifi_sys_wifi_on_req: Failed to get f/w\n");
+ unifi_sys_wifi_on_cfm(priv->smepriv, unifi_Error);
+ return;
+ }
+
+ /* Power on UniFi */
+ r = unifi_sdio_power_on(priv->sdio);
+ if (r < 0) {
+ unifi_error(priv, "unifi_sys_wifi_on_req: Failed to power on UniFi\n");
+ unifi_sys_wifi_on_cfm(priv->smepriv, unifi_Error);
+ return;
+ }
+
+ /* If unifi_sdio_power_on() returns 0, it means that we need to initialise UniFi */
+ if (r == 0) {
+ /* Initialise UniFi hardware */
+ r = uf_init_hw(priv);
+ if (r) {
+ unifi_error(priv, "unifi_sys_wifi_on_req: Failed to initialise h/w, error %d\n", r);
+ unifi_sys_wifi_on_cfm(priv->smepriv, unifi_Error);
+ return;
+ }
+ }
+
+ /* Start the I/O thread */
+ uf_init_bh(priv);
+
+ /* Get the version information from the core */
+ unifi_card_info(priv->card, &priv->card_info);
+
+ /* Copy to the unifiio_card_info structure. */
+ versions.chipId = priv->card_info.chip_id;
+ versions.chipVersion = priv->card_info.chip_version;
+ versions.firmwareBuild = priv->card_info.fw_build;
+ versions.firmwareHip = priv->card_info.fw_hip_version;
+ versions.driverBuild = UNIFI_DRIVER_BUILD_ID;
+ versions.driverHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
+ versions.smeDriverApi = (SME_API_MAJOR_VERSION << 8) | SME_API_MINOR_VERSION;
+ versions.smeIdString = "";
+
+ unifi_sys_wifi_on_ind(priv->smepriv, unifi_Success, &versions);
+
+ /* Update the wifi_on state */
+ priv->wifi_on_state = wifi_on_done;
+}
+
+
+/*
+ * wifi_off:
+ * Common code for unifi_sys_wifi_off_req() and
+ * unifi_sys_wifi_off_rsp().
+ */
+static void
+wifi_off(unifi_priv_t *priv)
+{
+ int power_off;
+ int priv_instance;
+
+ /* Destroy the Traffic Analysis Module */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ cancel_work_sync(&priv->ta_ind_work.task);
+ cancel_work_sync(&priv->ta_sample_ind_work.task);
+#ifdef CSR_SUPPORT_WEXT
+ cancel_work_sync(&priv->sme_config_task);
+#endif
+#endif
+ flush_workqueue(priv->unifi_workqueue);
+
+ /* fw_init parameter can prevent power off UniFi, for debugging */
+ priv_instance = unifi_find_priv(priv);
+ if (priv_instance == -1) {
+ unifi_warning(priv,
+ "unifi_sys_stop_req: Unknown priv instance, will power off card.\n");
+ power_off = 1;
+ } else {
+ power_off = (fw_init[priv_instance] > 0) ? 0 : 1;
+ }
+
+ /* Stop the bh_thread */
+ uf_stop_thread(priv, &priv->bh_thread);
+
+ if (power_off) {
+ unifi_trace(priv, UDBG2,
+ "Force low power and try to power off\n");
+ /* Put UniFi to deep sleep, in case we can not power it off */
+ uf_sdio_claim(priv->sdio);
+ unifi_force_low_power_mode(priv->card);
+ uf_sdio_release(priv->sdio);
+
+ unifi_sdio_power_off(priv->sdio);
+ }
+
+ /* Consider UniFi to be uninitialised */
+ priv->init_progress = UNIFI_INIT_NONE;
+
+} /* wifi_off() */
+
+
+void unifi_sys_wifi_off_req(void* drvpriv)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ return;
+ }
+
+ unifi_trace(priv, UDBG1, "unifi_sys_wifi_off_req:\n");
+
+
+ /* Stop the network traffic before freeing the core. */
+ if (priv->netdev_registered == 1) {
+ netif_carrier_off(priv->netdev);
+ UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev);
+ }
+
+ wifi_off(priv);
+
+ unifi_sys_wifi_off_cfm(priv->smepriv);
+}
+
+
+void unifi_sys_qos_control_req(void* drvpriv, unifi_QoSControl control)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "unifi_sys_qos_control_req: invalid smepriv\n");
+ return;
+ }
+
+ unifi_trace(priv, UDBG4,
+ "unifi_sys_qos_control_req: control = %d", control);
+
+ if (control == unifi_QoSWMMOn) {
+ priv->sta_wmm_capabilities |= QOS_CAPABILITY_WMM_ENABLED;
+ } else {
+ priv->sta_wmm_capabilities = 0;
+ }
+
+ unifi_sys_qos_control_cfm(priv->smepriv, unifi_Success);
+}
+
+
+void unifi_sys_tclas_add_req(void* drvpriv, const unifi_DataBlock* tclas)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(priv, "unifi_sys_tclas_add_req: invalid smepriv\n");
+ return;
+ }
+
+ unifi_sys_tclas_add_cfm(priv->smepriv, unifi_Success);
+}
+
+
+void unifi_sys_tclas_del_req(void* drvpriv, const unifi_DataBlock* tclas)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(priv, "unifi_sys_tclas_del_req: invalid smepriv\n");
+ return;
+ }
+
+ unifi_sys_tclas_del_cfm(priv->smepriv, unifi_Success);
+}
+
+
+void unifi_sys_configure_power_mode_req(void* drvpriv, unifi_LowPowerMode mode, Boolean wakeHost)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ enum unifi_low_power_mode pm;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "unifi_sys_hw_check_req: invalid smepriv\n");
+ return;
+ }
+
+ if (mode == unifi_LowPowerDisabled) {
+ pm = UNIFI_LOW_POWER_DISABLED;
+ } else {
+ pm = UNIFI_LOW_POWER_ENABLED;
+ }
+
+ unifi_trace(priv, UDBG2,
+ "unifi_sys_configure_power_mode_req (mode=%d, wake=%d)\n",
+ mode, wakeHost);
+ unifi_configure_low_power_mode(priv->card, pm,
+ (wakeHost ? UNIFI_PERIODIC_WAKE_HOST_ENABLED : UNIFI_PERIODIC_WAKE_HOST_DISABLED));
+}
+
+
+void unifi_sys_wifi_on_rsp(void* drvpriv, unifi_Status status,
+ const unifi_MACAddress *stationMacAddress)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(NULL, "unifi_sys_wifi_on_rsp: Invalid ospriv.\n");
+ return;
+ }
+
+ unifi_trace(priv, UDBG1,
+ "unifi_sys_wifi_on_rsp: status %d\n", status);
+
+ /* UniFi is now initialised, complete the init. */
+ if (status == unifi_Success)
+ {
+ /* Register the UniFi device with the OS network manager */
+ unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");
+
+ /* Store the MAC address in the netdev */
+ memcpy(priv->netdev->dev_addr, stationMacAddress->data, ETH_ALEN);
+
+ if (!priv->netdev_registered)
+ {
+ int r;
+ unifi_trace(priv, UDBG1, "registering net device\n");
+ r = uf_register_netdev(priv);
+ if (r) {
+ unifi_error(priv, "Failed to register the network device.\n");
+ unifi_sys_wifi_on_cfm(priv->smepriv, unifi_Error);
+ return;
+ }
+ }
+
+ priv->init_progress = UNIFI_INIT_COMPLETED;
+
+ /* Acknowledge the unifi_sys_wifi_on_req() now */
+ unifi_sys_wifi_on_cfm(priv->smepriv, unifi_Success);
+
+ unifi_info(priv, "UniFi ready\n");
+
+#ifdef CSR_SUPPORT_WEXT
+ queue_work(priv->unifi_workqueue, &priv->sme_config_task);
+#endif
+
+ } else {
+ /* Acknowledge the unifi_sys_wifi_on_req() now */
+ unifi_sys_wifi_on_cfm(priv->smepriv, unifi_Error);
+ }
+}
+
+
+void unifi_sys_wifi_off_rsp(void* drvpriv)
+{
+}
+
+
+void unifi_sys_multicast_address_rsp(void* drvpriv, unifi_Status status,
+ unifi_ListAction action,
+ const unifi_MulticastAddressList* addresses)
+{
+}
+
+
+void unifi_sys_suspend_rsp(void* drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(priv, "unifi_sys_suspend_rsp: invalid priv\n");
+ return;
+ }
+
+ sme_complete_request(priv, status);
+}
+
+
+void unifi_sys_resume_rsp(void* drvpriv, unifi_Status status)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(priv, "unifi_sys_resume_rsp: invalid priv\n");
+ return;
+ }
+
+ /*
+ * Nothing is waiting for the response.
+ * Do not call sme_complete_request(), otherwise the driver
+ * and the SME will be out of step.
+ */
+}
+
+
+int sme_sys_suspend(unifi_priv_t *priv)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_sys_suspend: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_sys_suspend_ind(priv->smepriv, 0, 0);
+ r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
+ if (r) {
+ unifi_notice(priv,
+ "suspend: SME did not reply, power off UniFi anyway\n");
+ }
+
+ /* Put UniFi to deep sleep, in case we can not power it off */
+ uf_sdio_claim(priv->sdio);
+ unifi_force_low_power_mode(priv->card);
+ uf_sdio_release(priv->sdio);
+
+ unifi_sdio_power_off(priv->sdio);
+
+ /* Consider UniFi to be uninitialised */
+ priv->init_progress = UNIFI_INIT_NONE;
+
+ unifi_trace(priv, UDBG1, "sme_sys_suspend: <-- (%d)\n", r);
+ return convert_sme_error(priv->sme_reply.reply_status);
+}
+
+
+int sme_sys_resume(unifi_priv_t *priv)
+{
+ int r;
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_sys_resume: invalid smepriv\n");
+ return -EIO;
+ }
+
+ r = sme_init_request(priv);
+ if (r) {
+ return -EIO;
+ }
+
+ unifi_sys_resume_ind(priv->smepriv, 0);
+
+ /*
+ * We are not going to wait for the reply because the SME might be in
+ * the userspace. In this case the event will reach it when the kernel
+ * resumes. So, release now the SME semaphore that was downed in
+ * sme_init_request().
+ */
+ up(&priv->sme_sem);
+ return 0;
+}
+
+void unifi_sys_traffic_config_req(void* drvpriv, unifi_traffic_configtype type, const unifi_traffic_config *config)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(priv, "unifi_sys_traffic_config_req: invalid smepriv\n");
+ return;
+ }
+
+ unifi_ta_configure(priv->card, type, config);
+}
+
+void unifi_sys_traffic_classification_req(void* drvpriv, unifi_traffic_type traffic_type, uint16 period)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+
+ if (priv == NULL) {
+ unifi_error(priv, "unifi_sys_traffic_classification_req: invalid smepriv\n");
+ return;
+ }
+
+ unifi_ta_classification(priv->card, traffic_type, period);
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_wext.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_wext.c
new file mode 100644
index 0000000..10e0d34
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/sme_wext.c
@@ -0,0 +1,2455 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: sme_wext.c
+ *
+ * PURPOSE:
+ * Handlers for ioctls from iwconfig.
+ * These provide the control plane operations.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/types.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+#include "unifi_priv.h"
+
+#ifdef CSR_SME_EMB
+#include "fsm/fsm_debug.h"
+#endif
+
+#define IWPRIV_POWER_SAVE_MAX_STRING 32
+#define SIOCIWS80211POWERSAVEPRIV SIOCIWFIRSTPRIV
+#define SIOCIWG80211POWERSAVEPRIV SIOCIWFIRSTPRIV + 1
+#define SIOCIWS80211RELOADDEFAULTSPRIV SIOCIWFIRSTPRIV + 2
+#define SIOCIWSSMEDEBUGDUMPPRIV SIOCIWFIRSTPRIV + 3
+
+
+#define CHECK_INITED(_priv) \
+do { \
+ if (_priv->init_progress != UNIFI_INIT_COMPLETED) { \
+ unifi_trace(_priv, UDBG2, "%s unifi not ready, failing wext call\n", __FUNCTION__); \
+ return -ENODEV; \
+ } \
+} while (0)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Helper functions
+ * ---------------------------------------------------------------------------
+ */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * wext_freq_to_channel
+ * channel_to_mhz
+ *
+ * These functions convert between channel number and frequency.
+ *
+ * Arguments:
+ * ch Channel number, as defined in 802.11 specs
+ * m, e Mantissa and exponent as provided by wireless extension.
+ *
+ * Returns:
+ * channel or frequency (in MHz) value
+ * ---------------------------------------------------------------------------
+ */
+static int
+wext_freq_to_channel(int m, int e)
+{
+ int mhz;
+
+ mhz = m;
+ while (e < 6) {
+ mhz /= 10;
+ e++;
+ }
+ while (e > 6) {
+ mhz *= 10;
+ e--;
+ }
+
+ if (mhz >= 5000) {
+ return ((mhz - 5000) / 5);
+ }
+
+ if (mhz == 2482) {
+ return 14;
+ }
+
+ if (mhz >= 2407) {
+ return ((mhz - 2407) / 5);
+ }
+
+ return 0;
+} /* wext_freq_to_channel() */
+
+static int
+channel_to_mhz(int ch, int dot11a)
+{
+
+ if (ch == 0) return 0;
+ if (ch > 200) return 0;
+
+ /* 5G */
+ if (dot11a) {
+ return (5000 + (5 * ch));
+ }
+
+ /* 2.4G */
+ if (ch == 14) {
+ return 2484;
+ }
+
+ if ((ch < 14) && (ch > 0)) {
+ return (2407 + (5 * ch));
+ }
+
+ return 0;
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sme_wext_set_defaults
+ *
+ * Set up power-on defaults for driver config.
+ *
+ * Note: The SME Management API *cannot* be used in this function.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+uf_sme_wext_set_defaults(unifi_priv_t *priv)
+{
+ memset(&priv->connection_config, 0, sizeof(unifi_ConnectionConfig));
+
+ priv->connection_config.bssType = unifi_Infrastructure;
+ priv->connection_config.authMode = unifi_80211_AuthOpen;
+ priv->connection_config.encryptionMode = unifi_EncryptionCipherNone;
+ priv->connection_config.privacyMode = unifi_80211_PrivacyDisabled;
+ priv->connection_config.wmmQosInfo = 0xFF;
+
+ priv->wep_tx_key_index = 0;
+
+ priv->wext_wireless_stats.qual.qual = 0;
+ priv->wext_wireless_stats.qual.level = 0;
+ priv->wext_wireless_stats.qual.noise = 0;
+ priv->wext_wireless_stats.qual.updated = 0x70;
+
+ priv->cached_tx_rate = 0;
+} /* uf_sme_wext_set_defaults() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * WEXT methods
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_giwname - handler for SIOCGIWNAME
+ * unifi_siwfreq - handler for SIOCSIWFREQ
+ * unifi_giwfreq - handler for SIOCGIWFREQ
+ * unifi_siwmode - handler for SIOCSIWMODE
+ * unifi_giwmode - handler for SIOCGIWMODE
+ * unifi_giwrange - handler for SIOCGIWRANGE
+ * unifi_siwap - handler for SIOCSIWAP
+ * unifi_giwap - handler for SIOCGIWAP
+ * unifi_siwscan - handler for SIOCSIWSCAN
+ * unifi_giwscan - handler for SIOCGIWSCAN
+ * unifi_siwessid - handler for SIOCSIWESSID
+ * unifi_giwessid - handler for SIOCGIWESSID
+ * unifi_siwencode - handler for SIOCSIWENCODE
+ * unifi_giwencode - handler for SIOCGIWENCODE
+ *
+ * Handler functions for IW extensions.
+ * These are registered via the unifi_iw_handler_def struct below
+ * and called by the generic IW driver support code.
+ * See include/net/iw_handler.h.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+iwprivsdefs(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r;
+ unifi_AppValue sme_app_value;
+
+ unifi_trace(priv, UDBG1, "iwprivs80211defaults: reload defaults\n");
+
+ uf_sme_wext_set_defaults(priv);
+
+ /* Get, modify and set the MIB data */
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "iwprivs80211defaults: Get unifi_MibConfigValue failed.\n");
+ return r;
+ }
+ sme_app_value.unifi_Value_union.mibConfig.dot11RTSThreshold = 2347;
+ sme_app_value.unifi_Value_union.mibConfig.dot11FragmentationThreshold = 2346;
+ r = sme_mgt_set_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "iwprivs80211defaults: Set unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveLow;
+ sme_app_value.unifi_Value_union.powerConfig.listenInterval = 100;
+ sme_app_value.unifi_Value_union.powerConfig.rxDtims = 1;
+ sme_app_value.id = unifi_PowerConfigValue;
+
+ r = sme_mgt_set_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "iwprivs80211defaults: Set unifi_PowerConfigValue failed.\n");
+ return r;
+ }
+
+ return 0;
+} /* iwprivsdefs() */
+
+static int
+iwprivs80211ps(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r = 0;
+ int ps_mode = (int)(*extra);
+ unifi_AppValue sme_app_value;
+
+ unifi_trace(priv, UDBG1, "iwprivs80211ps: power save mode = %d\n", ps_mode);
+
+ sme_app_value.id = unifi_PowerConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "iwprivs80211ps: Get unifi_PowerConfigValue failed.\n");
+ return r;
+ }
+
+ switch (ps_mode) {
+ case CSR_PMM_ACTIVE_MODE:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveLow;
+ break;
+ case CSR_PMM_POWER_SAVE:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveHigh;
+ break;
+ case CSR_PMM_FAST_POWER_SAVE:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveMed;
+ break;
+ default:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveAuto;
+ break;
+ }
+
+ sme_app_value.id = unifi_PowerConfigValue;
+ r = sme_mgt_set_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "iwprivs80211ps: Set unifi_PowerConfigValue failed.\n");
+ }
+
+ return r;
+}
+
+static int
+iwprivg80211ps(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ unifi_AppValue sme_app_value;
+ int r;
+
+ sme_app_value.id = unifi_PowerConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "iwprivg80211ps: Get 802.11 power mode failed.\n");
+ return r;
+ }
+
+ switch (sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel) {
+ case unifi_PowerSaveLow:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Active)",
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel);
+ break;
+ case unifi_PowerSaveMed:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Fast)",
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel);
+ break;
+ case unifi_PowerSaveHigh:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Full)",
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel);
+ break;
+ case unifi_PowerSaveAuto:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Auto)",
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel);
+ break;
+ default:
+ snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
+ "Power save mode: %d (Unknown)",
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel);
+ break;
+ }
+
+ wrqu->data.length = strlen(extra) + 1;
+
+ return 0;
+}
+
+static int
+iwprivssmedebugdump(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ if (priv->smepriv != NULL) {
+#ifdef CSR_SME_EMB
+ fsm_debug_dump(priv->smepriv);
+#endif
+ }
+ return 0;
+}
+
+
+static int
+unifi_giwname(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ char *name = wrqu->name;
+
+ if (priv->if_index == CSR_INDEX_5G) {
+ strcpy(name, "IEEE 802.11-a");
+ } else {
+ strcpy(name, "IEEE 802.11-b/g");
+ }
+ return 0;
+} /* unifi_giwname() */
+
+
+static int
+unifi_siwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_freq *freq = (struct iw_freq *)wrqu;
+
+ func_enter();
+
+ /*
+ * Channel is stored in the connection configuration,
+ * and set later when ask for a connection.
+ */
+ if ((freq->e == 0) && (freq->m <= 1000)) {
+ priv->connection_config.adhocChannel = freq->m;
+ } else {
+ priv->connection_config.adhocChannel = wext_freq_to_channel(freq->m, freq->e);
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_siwfreq() */
+
+
+static int
+unifi_giwfreq(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_freq *freq = (struct iw_freq *)wrqu;
+ int err = 0;
+ unifi_AppValue sme_app_value;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ sme_app_value.id = unifi_ConnectionInfoValue;
+ err = sme_mgt_get_value(priv, &sme_app_value);
+ freq->m = sme_app_value.unifi_Value_union.connectionInfo.channelNumber;
+ freq->e = 0;
+
+
+ func_exit();
+ return convert_sme_error(err);
+} /* unifi_giwfreq() */
+
+
+static int
+unifi_siwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ func_enter();
+
+ switch(wrqu->mode) {
+ case IW_MODE_ADHOC:
+ priv->connection_config.bssType = unifi_Adhoc;
+ break;
+ case IW_MODE_INFRA:
+ priv->connection_config.bssType = unifi_Infrastructure;
+ break;
+ case IW_MODE_AUTO:
+ /* FIXME: Auto mode is needed */
+ priv->connection_config.bssType = unifi_Infrastructure;
+ break;
+ default:
+ unifi_notice(priv, "Unknown IW MODE value.\n");
+ }
+
+ /* Clear the SSID and BSSID configuration */
+ priv->connection_config.ssid.length = 0;
+ memset(priv->connection_config.bssid.data, 0xFF, ETH_ALEN);
+
+ func_exit();
+ return 0;
+} /* unifi_siwmode() */
+
+
+
+static int
+unifi_giwmode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r = 0;
+ unifi_AppValue sme_app_value;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ sme_app_value.id = unifi_ConnectionConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r == 0) {
+ switch(sme_app_value.unifi_Value_union.connectionConfig.bssType) {
+ case unifi_Adhoc:
+ wrqu->mode = IW_MODE_ADHOC;
+ break;
+ case unifi_Infrastructure:
+ wrqu->mode = IW_MODE_INFRA;
+ break;
+ default:
+ wrqu->mode = IW_MODE_AUTO;
+ unifi_notice(priv, "Unknown IW MODE value.\n");
+ }
+ }
+
+ unifi_trace(priv, UDBG4, "unifi_giwmode: mode = %d\n", wrqu->mode);
+ func_exit();
+ return r;
+} /* unifi_giwmode() */
+
+
+
+static int
+unifi_giwrange(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_point *dwrq = &wrqu->data;
+ struct iw_range *range = (struct iw_range *) extra;
+ int i;
+
+ dwrq->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(*range));
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x0000;
+
+ /*
+ * Don't report the frequency/channel table, then the channel
+ * number returned elsewhere will be printed as a channel number.
+ */
+
+ /* Ranges of values reported in quality structs */
+ range->max_qual.qual = 40; /* Max expected qual value */
+ range->max_qual.level = -120; /* Noise floor in dBm */
+ range->max_qual.noise = -120; /* Noise floor in dBm */
+
+
+ /* space for IW_MAX_BITRATES (8 up to WE15, 32 later) */
+ i = 0;
+#if WIRELESS_EXT > 15
+ range->bitrate[i++] = 2 * 500000;
+ range->bitrate[i++] = 4 * 500000;
+ range->bitrate[i++] = 11 * 500000;
+ range->bitrate[i++] = 22 * 500000;
+ range->bitrate[i++] = 12 * 500000;
+ range->bitrate[i++] = 18 * 500000;
+ range->bitrate[i++] = 24 * 500000;
+ range->bitrate[i++] = 36 * 500000;
+ range->bitrate[i++] = 48 * 500000;
+ range->bitrate[i++] = 72 * 500000;
+ range->bitrate[i++] = 96 * 500000;
+ range->bitrate[i++] = 108 * 500000;
+#else
+ range->bitrate[i++] = 2 * 500000;
+ range->bitrate[i++] = 4 * 500000;
+ range->bitrate[i++] = 11 * 500000;
+ range->bitrate[i++] = 22 * 500000;
+ range->bitrate[i++] = 24 * 500000;
+ range->bitrate[i++] = 48 * 500000;
+ range->bitrate[i++] = 96 * 500000;
+ range->bitrate[i++] = 108 * 500000;
+#endif /* WIRELESS_EXT < 16 */
+ range->num_bitrates = i;
+
+ range->max_encoding_tokens = NUM_WEPKEYS;
+ range->num_encoding_sizes = 2;
+ range->encoding_size[0] = 5;
+ range->encoding_size[1] = 13;
+
+ range->we_version_source = 20;
+ range->we_version_compiled = WIRELESS_EXT;
+
+ /* Number of channels available in h/w */
+ range->num_channels = 14;
+ /* Number of entries in freq[] array */
+ range->num_frequency = 14;
+ for (i = 0; i < range->num_frequency; i++) {
+ int chan = i + 1;
+ range->freq[i].i = chan;
+ range->freq[i].m = channel_to_mhz(chan, 0);
+ range->freq[i].e = 6;
+ }
+
+#if WIRELESS_EXT > 16
+ /* Event capability (kernel + driver) */
+ range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+ IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
+ IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+ IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
+ range->event_capa[1] = IW_EVENT_CAPA_K_1;
+ range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
+ IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
+ IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
+ IW_EVENT_CAPA_MASK(IWEVEXPIRED));
+#endif /* WIRELESS_EXT > 16 */
+
+#if WIRELESS_EXT > 17
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif /* WIRELESS_EXT > 17 */
+
+
+ return 0;
+} /* unifi_giwrange() */
+
+
+static int
+unifi_siwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int err = 0;
+ const unsigned char zero_bssid[ETH_ALEN] = {0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00};
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) {
+ return -EINVAL;
+ }
+
+ unifi_trace(priv, UDBG1, "unifi_siwap: asked for %02X:%02X:%02X:%02X:%02X:%02X\n",
+ (u8)wrqu->ap_addr.sa_data[0],
+ (u8)wrqu->ap_addr.sa_data[1],
+ (u8)wrqu->ap_addr.sa_data[2],
+ (u8)wrqu->ap_addr.sa_data[3],
+ (u8)wrqu->ap_addr.sa_data[4],
+ (u8)wrqu->ap_addr.sa_data[5]);
+
+ if (!memcmp(wrqu->ap_addr.sa_data, zero_bssid, ETH_ALEN)) {
+ priv->ignore_bssid_join = FALSE;
+ err = sme_mgt_disconnect(priv);
+ if (err) {
+ unifi_trace(priv, UDBG4, "unifi_siwap: Disconnect failed, status %d\n", err);
+ }
+ return 0;
+ }
+
+ if (priv->ignore_bssid_join) {
+ unifi_trace(priv, UDBG4, "unifi_siwap: ignoring second join\n");
+ priv->ignore_bssid_join = FALSE;
+ } else {
+ memcpy(priv->connection_config.bssid.data, wrqu->ap_addr.sa_data, ETH_ALEN);
+ unifi_trace(priv, UDBG1, "unifi_siwap: Joining %X:%X:%X:%X:%X:%X\n",
+ priv->connection_config.bssid.data[0],
+ priv->connection_config.bssid.data[1],
+ priv->connection_config.bssid.data[2],
+ priv->connection_config.bssid.data[3],
+ priv->connection_config.bssid.data[4],
+ priv->connection_config.bssid.data[5]);
+ err = sme_mgt_connect(priv);
+ if (err) {
+ unifi_error(priv, "unifi_siwap: Join failed, status %d\n", err);
+ func_exit();
+ return convert_sme_error(err);
+ }
+ }
+ func_exit();
+
+ return 0;
+} /* unifi_siwap() */
+
+
+static int
+unifi_giwap(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ unifi_AppValue sme_app_value;
+ int r = 0;
+ uint8 *bssid;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ sme_app_value.id = unifi_ConnectionInfoValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+
+ if (r == 0) {
+ bssid = sme_app_value.unifi_Value_union.connectionInfo.bssid.data;
+ wrqu->ap_addr.sa_family = ARPHRD_ETHER;
+ unifi_trace(priv, UDBG4,
+ "unifi_giwap: BSSID = %02X:%02X:%02X:%02X:%02X:%02X\n",
+ bssid[0], bssid[1], bssid[2],
+ bssid[3], bssid[4], bssid[5]);
+
+ memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
+ } else {
+ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_giwap() */
+
+
+static int
+unifi_siwscan(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int scantype;
+ int r;
+ unifi_SSID scan_ssid;
+#if WIRELESS_EXT > 17
+ struct iw_point *data = &wrqu->data;
+ struct iw_scan_req *req = (struct iw_scan_req *) extra;
+#endif
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ scantype = UNIFI_SCAN_ACTIVE;
+
+#if WIRELESS_EXT > 17
+ if (req && (data->flags & IW_SCAN_THIS_ESSID)) {
+ memcpy(scan_ssid.ssid, req->essid, req->essid_len);
+ scan_ssid.length = req->essid_len;
+ unifi_trace(priv, UDBG1,
+ "SIWSCAN: Scanning for %.*s\n",
+ scan_ssid.length, scan_ssid.ssid);
+ } else
+#endif
+ {
+ unifi_trace(priv, UDBG1, "SIWSCAN: Scanning for all APs\n");
+ scan_ssid.length = 0;
+ }
+
+ r = sme_mgt_scan_full(priv, &scan_ssid);
+ if (r) {
+ unifi_error(priv, "SIWSCAN: Scan returned error %d\n", r);
+ } else {
+ unifi_trace(priv, UDBG1, "SIWSCAN: Scan done\n");
+ wext_send_scan_results_event(priv);
+ }
+
+ func_exit();
+ return r;
+
+} /* unifi_siwscan() */
+
+
+static const unsigned char *
+unifi_find_info_element(int id, const unsigned char *info, int len)
+{
+ const unsigned char *ie = info;
+
+ while (len > 1)
+ {
+ int e_id, e_len;
+ e_id = ie[0];
+ e_len = ie[1];
+
+ /* Return if we find a match */
+ if (e_id == id)
+ {
+ return ie;
+ }
+
+ len -= (e_len + 2);
+ ie += (e_len + 2);
+ }
+
+ return NULL;
+} /* unifi_find_info_element() */
+
+
+/*
+ * Translate scan data returned from the card to a card independent
+ * format that the Wireless Tools will understand - Jean II
+ */
+int
+unifi_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ char *current_ev, char *end_buf,
+ unifi_ScanResult *scan_data,
+ int scan_index)
+{
+ struct iw_event iwe; /* Temporary buffer */
+ unsigned char *info_elems;
+ int info_elem_len;
+ const unsigned char *elem;
+ u16 capabilities;
+ int signal, noise, snr;
+ char *start_buf = current_ev;
+ char *current_val; /* For rates */
+ int i, r;
+
+ info_elems = scan_data->informationElements.data;
+ info_elem_len = scan_data->informationElements.length;
+
+ if (!scan_data->informationElements.length || !scan_data->informationElements.data) {
+ unifi_error(NULL, "*** NULL SCAN IEs ***\n");
+ return -EIO;
+ }
+
+ /* get capinfo bits */
+ capabilities = scan_data->capabilityInformation;
+
+ unifi_trace(NULL, UDBG5, "Capabilities: 0x%x\n", capabilities);
+
+ /* First entry *MUST* be the AP MAC address */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, scan_data->bssid.data, ETH_ALEN);
+ iwe.len = IW_EV_ADDR_LEN;
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_ADDR_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ /* find SSID in Info Elems */
+ elem = unifi_find_info_element(IE_SSID_ID, info_elems, info_elem_len);
+ if (elem) {
+ int e_len = elem[1];
+ const unsigned char *e_ptr = elem + 2;
+ unsigned char buf[33];
+
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.essid.length = e_len;
+ if (iwe.u.essid.length > 32) {
+ iwe.u.essid.length = 32;
+ }
+ iwe.u.essid.flags = scan_index;
+ memcpy(buf, e_ptr, iwe.u.essid.length);
+ buf[iwe.u.essid.length] = '\0';
+ r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, buf);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+ }
+
+ /* Add mode */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWMODE;
+ if (scan_data->bssType == unifi_Infrastructure) {
+ iwe.u.mode = IW_MODE_INFRA;
+ } else {
+ iwe.u.mode = IW_MODE_ADHOC;
+ }
+ iwe.len = IW_EV_UINT_LEN;
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_UINT_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+ /* Add frequency. iwlist will convert to channel using table given in giwrange */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = scan_data->channelFrequency;
+ iwe.u.freq.e = 6;
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_FREQ_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+
+ /* Add quality statistics */
+ iwe.cmd = IWEVQUAL;
+ /*
+ * level and noise below are mapped into an unsigned 8 bit number,
+ * ranging from [-192; 63]. The way this is achieved is simply to
+ * add 0x100 onto the number if it is negative,
+ * once clipped to the correct range.
+ */
+ signal = scan_data->rssi; /* This value is in dBm */
+ /* Clip range of snr */
+ snr = (scan_data->snr > 0) ? scan_data->snr : 0; /* In dB relative, from 0 - 255 */
+ snr = (snr < 255) ? snr : 255;
+ noise = signal - snr;
+
+ /* Clip range of signal */
+ signal = (signal < 63) ? signal : 63;
+ signal = (signal > -192) ? signal : -192;
+
+ /* Clip range of noise */
+ noise = (noise < 63) ? noise : 63;
+ noise = (noise > -192) ? noise : -192;
+
+ /* Make u8 */
+ signal = ( signal < 0 ) ? signal + 0x100 : signal;
+ noise = ( noise < 0 ) ? noise + 0x100 : noise;
+
+ iwe.u.qual.level = (u8)signal; /* -192 : 63 */
+ iwe.u.qual.noise = (u8)noise; /* -192 : 63 */
+ iwe.u.qual.qual = snr; /* 0 : 255 */
+ iwe.u.qual.updated = 0;
+#if WIRELESS_EXT > 16
+ iwe.u.qual.updated |= IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED |
+ IW_QUAL_QUAL_UPDATED;
+#if WIRELESS_EXT > 18
+ iwe.u.qual.updated |= IW_QUAL_DBM;
+#endif
+#endif
+ r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_QUAL_LEN);
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & SIG_CAP_PRIVACY) {
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ } else {
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ }
+ iwe.u.data.length = 0;
+ iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+ r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, "");
+ if (r < 0) {
+ return r;
+ }
+ start_buf += r;
+
+
+ /*
+ * Rate : stuffing multiple values in a single event require a bit
+ * more of magic - Jean II
+ */
+ current_val = start_buf + IW_EV_LCP_LEN;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ elem = unifi_find_info_element(IE_SUPPORTED_RATES_ID,
+ info_elems, info_elem_len);
+ if (elem) {
+ int e_len = elem[1];
+ const unsigned char *e_ptr = elem + 2;
+
+ /*
+ * Count how many rates we have.
+ * Zero marks the end of the list, if the list is not truncated.
+ */
+ /* Max 8 values */
+ for (i = 0; i < e_len; i++) {
+ if (e_ptr[i] == 0) {
+ break;
+ }
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ if (r < 0) {
+ return r;
+ }
+ current_val +=r;
+
+ }
+ }
+ elem = unifi_find_info_element(IE_EXTENDED_SUPPORTED_RATES_ID,
+ info_elems, info_elem_len);
+ if (elem) {
+ int e_len = elem[1];
+ const unsigned char *e_ptr = elem + 2;
+
+ /*
+ * Count how many rates we have.
+ * Zero marks the end of the list, if the list is not truncated.
+ */
+ /* Max 8 values */
+ for (i = 0; i < e_len; i++) {
+ if (e_ptr[i] == 0) {
+ break;
+ }
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ if (r < 0) {
+ return r;
+ }
+ current_val +=r;
+ }
+ }
+ /* Check if we added any rates event */
+ if ((current_val - start_buf) > IW_EV_LCP_LEN) {
+ start_buf = current_val;
+ }
+
+
+#if WIRELESS_EXT > 17
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = info_elem_len;
+
+ r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, info_elems);
+ if (r < 0) {
+ return r;
+ }
+
+ start_buf += r;
+#endif /* WE > 17 */
+
+ return (start_buf - current_ev);
+} /* unifi_translate_scan() */
+
+
+
+static int
+unifi_giwscan(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *dwrq = &wrqu->data;
+ int r;
+
+ CHECK_INITED(priv);
+
+ unifi_trace(priv, UDBG1,
+ "unifi_giwscan: buffer (%d bytes) \n",
+ dwrq->length);
+ r = sme_mgt_scan_results_get_async(priv, info, extra, dwrq->length);
+ if (r < 0) {
+ unifi_trace(priv, UDBG1,
+ "unifi_giwscan: buffer (%d bytes) not big enough.\n",
+ dwrq->length);
+ return r;
+ }
+
+ dwrq->length = r;
+ dwrq->flags = 0;
+
+ return 0;
+} /* unifi_giwscan() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwessid
+ *
+ * Request to join a network or start and AdHoc.
+ *
+ * Arguments:
+ * dev Pointer to network device struct.
+ * info Pointer to broken-out ioctl request.
+ * data Pointer to argument data.
+ * essid Pointer to string giving name of network to join
+ * or start
+ *
+ * Returns:
+ * 0 on success and everything complete
+ * -EINPROGRESS to have the higher level call the commit method.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwessid(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ unifi_priv_t *priv = dev->priv;
+ int len;
+ int err = 0;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ len = 0;
+ if (data->flags & 1) {
+ /* Limit length */
+ len = data->length;
+ if (len > UNIFI_MAX_SSID_LEN) {
+ len = UNIFI_MAX_SSID_LEN;
+ }
+ }
+
+ unifi_trace(priv, UDBG1, "unifi_siwessid: asked for %*s\n", len, essid);
+
+ memset(priv->connection_config.bssid.data, 0xFF, ETH_ALEN);
+ if (len) {
+ if (essid[len - 1] == 0) {
+ len --;
+ }
+ memcpy(priv->connection_config.ssid.ssid, essid, len);
+ priv->connection_config.ssid.length = len;
+
+ } else {
+ priv->connection_config.ssid.length = 0;
+ }
+
+ err = sme_mgt_connect(priv);
+ if (err) {
+ unifi_error(priv, "unifi_siwessid: Join failed, status %d\n", err);
+ func_exit();
+ return convert_sme_error(err);
+ }
+
+ func_exit();
+ return 0;
+} /* unifi_siwessid() */
+
+
+static int
+unifi_giwessid(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *essid)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *data = &wrqu->essid;
+ unifi_AppValue sme_app_value;
+ int r = 0;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ sme_app_value.id = unifi_ConnectionInfoValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+
+ if (r == 0) {
+ data->length = sme_app_value.unifi_Value_union.connectionInfo.ssid.length;
+ strncpy(essid,
+ sme_app_value.unifi_Value_union.connectionInfo.ssid.ssid,
+ data->length);
+ data->flags = 1; /* active */
+
+ unifi_trace(priv, UDBG2, "unifi_giwessid: %.*s\n",
+ data->length, essid);
+ }
+
+ func_exit();
+
+ return 0;
+} /* unifi_giwessid() */
+
+
+static int
+unifi_siwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_param *args = &wrqu->bitrate;
+ unifi_AppValue sme_app_value;
+ int r;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ /*
+ * If args->fixed == 0, value is max rate or -1 for best
+ * If args->fixed == 1, value is rate to set or -1 for best
+ * args->disabled and args->flags are not used in SIOCSIWRATE
+ */
+
+ /* Get, modify and set the MIB data */
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwrate: Get unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ /* Default to auto rate algorithm */
+ /* in 500Kbit/s, 0 means auto */
+ sme_app_value.unifi_Value_union.mibConfig.unifiFixTxDataRate = 0;
+
+ if (args->value != -1) {
+ sme_app_value.unifi_Value_union.mibConfig.unifiFixTxDataRate = args->value / 500000;
+ }
+
+ /* 1 means rate is a maximum, 2 means rate is a set value */
+ if (args->fixed == 1) {
+ sme_app_value.unifi_Value_union.mibConfig.unifiFixMaxTxDataRate = 0;
+ } else {
+ sme_app_value.unifi_Value_union.mibConfig.unifiFixMaxTxDataRate = 1;
+ }
+
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_set_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwrate: Set unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ func_exit();
+
+ return 0;
+} /* unifi_siwrate() */
+
+
+
+static int
+unifi_giwrate(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_param *args = &wrqu->bitrate;
+ int r;
+ int bitrate, flag;
+ unifi_AppValue sme_app_value;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ flag = 0;
+ bitrate = 0;
+
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwrate: Get unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ bitrate = sme_app_value.unifi_Value_union.mibConfig.unifiFixTxDataRate;
+ /* Used the cached value returned by the SME if MIB returns 0 */
+ if (bitrate == 0) {
+ bitrate = priv->cached_tx_rate;
+ }
+
+ flag = sme_app_value.unifi_Value_union.mibConfig.unifiFixMaxTxDataRate;
+
+ args->value = bitrate * 500000;
+ args->fixed = !flag;
+
+ func_exit();
+
+ return 0;
+} /* unifi_giwrate() */
+
+
+static int
+unifi_siwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int val = wrqu->rts.value;
+ int r = 0;
+ unifi_AppValue sme_app_value;
+
+ CHECK_INITED(priv);
+
+ if (wrqu->rts.disabled) {
+ val = 2347;
+ }
+
+ if ( (val < 0) || (val > 2347) )
+ {
+ return -EINVAL;
+ }
+
+ /* Get, modify and set the MIB data */
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwrts: Get unifi_MibConfigValue failed.\n");
+ return r;
+ }
+ sme_app_value.unifi_Value_union.mibConfig.dot11RTSThreshold = val;
+ r = sme_mgt_set_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwrts: Set unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+static int
+unifi_giwrts(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r;
+ int rts_thresh;
+ unifi_AppValue sme_app_value;
+
+ CHECK_INITED(priv);
+
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_giwrts: Get unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ rts_thresh = sme_app_value.unifi_Value_union.mibConfig.dot11RTSThreshold;
+ if (rts_thresh > 2347) {
+ rts_thresh = 2347;
+ }
+
+ wrqu->rts.value = rts_thresh;
+ wrqu->rts.disabled = (rts_thresh == 2347);
+ wrqu->rts.fixed = 1;
+
+ return 0;
+}
+
+
+static int
+unifi_siwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int val = wrqu->frag.value;
+ int r = 0;
+ unifi_AppValue sme_app_value;
+
+ CHECK_INITED(priv);
+
+ if (wrqu->frag.disabled)
+ val = 2346;
+
+ if ( (val < 256) || (val > 2347) )
+ return -EINVAL;
+
+ /* Get, modify and set the MIB data */
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwfrag: Get unifi_MibConfigValue failed.\n");
+ return r;
+ }
+ /* Fragmentation Threashold must be even */
+ sme_app_value.unifi_Value_union.mibConfig.dot11FragmentationThreshold = (val & ~0x1);
+ r = sme_mgt_set_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwfrag: Set unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+static int
+unifi_giwfrag(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int r;
+ int frag_thresh;
+ unifi_AppValue sme_app_value;
+
+ CHECK_INITED(priv);
+
+ sme_app_value.id = unifi_MIBConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_giwfrag: Get unifi_MibConfigValue failed.\n");
+ return r;
+ }
+
+ frag_thresh = sme_app_value.unifi_Value_union.mibConfig.dot11FragmentationThreshold;
+
+ /* Build the return structure */
+ wrqu->frag.value = frag_thresh;
+ wrqu->frag.disabled = (frag_thresh >= 2346);
+ wrqu->frag.fixed = 1;
+
+ return 0;
+}
+
+
+static int
+unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *erq = &wrqu->encoding;
+ int index;
+ int rc = 0;
+ int privacy = -1;
+ unifi_Key sme_key;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ /*
+ * Key index is encoded in the flags.
+ * 0 - use current default,
+ * 1-4 - if a key value is given set that key
+ * if not use that key
+ */
+ index = (erq->flags & IW_ENCODE_INDEX); /* key number, 1-4 */
+ if ((index < 0) || (index > 4)) {
+ unifi_error(priv, "unifi_siwencode: Request to set an invalid key (index:%d)", index);
+ return -EINVAL;
+ }
+
+ /*
+ * Basic checking: do we have a key to set ?
+ * The IW_ENCODE_NOKEY flag is set when no key is present (only change flags),
+ * but older versions rely on sending a key id 1-4.
+ */
+ if (erq->length > 0) {
+
+ /* Check the size of the key */
+ if ((erq->length > LARGE_KEY_SIZE) || (erq->length < SMALL_KEY_SIZE)) {
+ unifi_error(priv, "unifi_siwencode: Request to set an invalid key (length:%d)",
+ erq->length);
+ return -EINVAL;
+ }
+
+ /* Check the index (none (i.e. 0) means use current) */
+ if ((index < 1) || (index > 4)) {
+ /* If we do not have a previous key, use 1 as default */
+ if (!priv->wep_tx_key_index) {
+ priv->wep_tx_key_index = 1;
+ }
+ index = priv->wep_tx_key_index;
+ }
+
+ /* If we didn't have a key and a valid index is set, we want to remember it*/
+ if (!priv->wep_tx_key_index) {
+ priv->wep_tx_key_index = index;
+ }
+
+ unifi_trace(priv, UDBG1, "Tx key Index is %d\n", priv->wep_tx_key_index);
+
+ privacy = 1;
+
+ /* Check if the key is not marked as invalid */
+ if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
+
+ unifi_trace(priv, UDBG1, "New %s key (len=%d, index=%d)\n",
+ (priv->wep_tx_key_index == index) ? "tx" : "",
+ erq->length, index);
+
+ sme_key.wepTxKey = (priv->wep_tx_key_index == index);
+ if (priv->wep_tx_key_index == index) {
+ sme_key.keyType = unifi_PairwiseKey;
+ } else {
+ sme_key.keyType = unifi_GroupKey;
+ }
+ /* Key index is zero based in SME but 1 based in wext */
+ sme_key.keyIndex = (index - 1);
+ sme_key.keyLength = erq->length;
+ sme_key.authenticator = 0;
+ memset(sme_key.address.data, 0xFF, ETH_ALEN);
+ memcpy(sme_key.key, extra, erq->length);
+
+ rc = sme_mgt_key(priv, &sme_key, unifi_ListActionAdd);
+ if (rc) {
+ unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
+ return convert_sme_error(rc);
+ }
+
+ /* Store the key to be reported by the SIOCGIWENCODE handler */
+ priv->wep_keys[index - 1].len = erq->length;
+ memcpy(priv->wep_keys[index - 1].key, extra, erq->length);
+ }
+ } else {
+ /*
+ * No additional key data, so it must be a request to change the
+ * active key.
+ */
+ if (index != 0) {
+ unifi_trace(priv, UDBG1, "Tx key Index is %d\n", index - 1);
+
+ /* Store the index to be reported by the SIOCGIWENCODE handler */
+ priv->wep_tx_key_index = index;
+
+ sme_key.wepTxKey = 1;
+ sme_key.keyType = unifi_PairwiseKey;
+
+ /* Key index is zero based in SME but 1 based in wext */
+ sme_key.keyIndex = (index - 1);
+ sme_key.keyLength = 0;
+ sme_key.authenticator = 0;
+
+ rc = sme_mgt_key(priv, &sme_key, unifi_ListActionAdd);
+ if (rc) {
+ unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
+ return convert_sme_error(rc);
+ }
+
+ /* Turn on encryption */
+ privacy = 1;
+ }
+ }
+
+ /* Read the flags */
+ if (erq->flags & IW_ENCODE_DISABLED) {
+ /* disable encryption */
+ unifi_trace(priv, UDBG1, "disable WEP encryption\n");
+ privacy = 0;
+
+ priv->wep_tx_key_index = 0;
+
+ unifi_trace(priv, UDBG1, "IW_ENCODE_DISABLED: unifi_80211_AuthOpen\n");
+ priv->connection_config.authMode = unifi_80211_AuthOpen;
+ }
+
+ if (erq->flags & IW_ENCODE_RESTRICTED) {
+ /* Use shared key auth */
+ unifi_trace(priv, UDBG1, "IW_ENCODE_RESTRICTED: unifi_80211_AuthShared\n");
+ priv->connection_config.authMode = unifi_80211_AuthShared;
+
+ /* Turn on encryption */
+ privacy = 1;
+ }
+ if (erq->flags & IW_ENCODE_OPEN) {
+ unifi_trace(priv, UDBG1, "IW_ENCODE_OPEN: unifi_80211_AuthOpen\n");
+ priv->connection_config.authMode = unifi_80211_AuthOpen;
+ }
+
+ /* Commit the changes to flags if needed */
+ if (privacy != -1) {
+ priv->connection_config.privacyMode = privacy ? unifi_80211_PrivacyEnabled : unifi_80211_PrivacyDisabled;
+ priv->connection_config.encryptionMode = privacy ? (unifi_EncryptionCipherPairwiseWep40 |
+ unifi_EncryptionCipherPairwiseWep104 |
+ unifi_EncryptionCipherGroupWep40 |
+ unifi_EncryptionCipherGroupWep104) :
+ unifi_EncryptionCipherNone;
+ }
+
+ func_exit_r(rc);
+ return convert_sme_error(rc);
+
+} /* unifi_siwencode() */
+
+
+
+static int
+unifi_giwencode(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_point *erq = &wrqu->encoding;
+
+ CHECK_INITED(priv);
+
+ if (priv->connection_config.authMode == unifi_80211_AuthShared) {
+ erq->flags = IW_ENCODE_RESTRICTED;
+ }
+ else {
+ if (priv->connection_config.privacyMode == unifi_80211_PrivacyDisabled) {
+ erq->flags = IW_ENCODE_DISABLED;
+ } else {
+ erq->flags = IW_ENCODE_OPEN;
+ }
+ }
+
+ erq->length = 0;
+
+ if (erq->flags != IW_ENCODE_DISABLED) {
+ int index = priv->wep_tx_key_index;
+
+ if ((index > 0) && (index <= NUM_WEPKEYS)) {
+ erq->flags |= (index & IW_ENCODE_INDEX);
+ erq->length = priv->wep_keys[index - 1].len;
+ memcpy(extra, priv->wep_keys[index - 1].key, erq->length);
+ } else {
+ unifi_notice(priv, "unifi_giwencode: Surprise, do not have a valid key index (%d)\n",
+ index);
+ }
+ }
+
+ return 0;
+} /* unifi_giwencode() */
+
+
+static int
+unifi_siwpower(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_param *args = &wrqu->power;
+ unifi_priv_t *priv = dev->priv;
+ int listen_interval, wake_for_dtim;
+ int r = 0;
+ unifi_AppValue sme_app_value;
+
+ CHECK_INITED(priv);
+
+ sme_app_value.id = unifi_PowerConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwpower: Get unifi_PowerConfigValue failed.\n");
+ return r;
+ }
+
+ listen_interval = -1;
+ wake_for_dtim = -1;
+ if (args->disabled) {
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveLow;
+ }
+ else
+ {
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveHigh;
+
+ switch (args->flags & IW_POWER_TYPE) {
+ case 0:
+ /* not specified */
+ break;
+ case IW_POWER_PERIOD:
+ listen_interval = args->value / 1000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (args->flags & IW_POWER_MODE) {
+ case 0:
+ /* not specified */
+ break;
+ case IW_POWER_UNICAST_R:
+ /* not interested in broadcast packets */
+ wake_for_dtim = 0;
+ break;
+ case IW_POWER_ALL_R:
+ /* yes, we are interested in broadcast packets */
+ wake_for_dtim = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ if (listen_interval > 0) {
+ sme_app_value.unifi_Value_union.powerConfig.listenInterval = listen_interval;
+ unifi_trace(priv, UDBG4, "unifi_siwpower: new Listen Interval = %d.\n",
+ sme_app_value.unifi_Value_union.powerConfig.listenInterval);
+ }
+
+ if (wake_for_dtim >= 0) {
+ sme_app_value.unifi_Value_union.powerConfig.rxDtims = wake_for_dtim;
+ }
+
+ sme_app_value.id = unifi_PowerConfigValue;
+ r = sme_mgt_set_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_siwpower: Set unifi_PowerConfigValue failed.\n");
+ return r;
+ }
+
+ return 0;
+} /* unifi_siwpower() */
+
+
+static int
+unifi_giwpower(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct iw_param *args = &wrqu->power;
+ unifi_priv_t *priv = dev->priv;
+ unifi_AppValue sme_app_value;
+ int r;
+
+ CHECK_INITED(priv);
+
+ args->flags = 0;
+
+ sme_app_value.id = unifi_PowerConfigValue;
+ r = sme_mgt_get_value(priv, &sme_app_value);
+ if (r) {
+ unifi_error(priv, "unifi_giwpower: Get unifi_PowerConfigValue failed.\n");
+ return r;
+ }
+
+ unifi_trace(priv, UDBG4, "unifi_giwpower: mode=%d\n",
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel);
+
+ args->disabled = (sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel == unifi_PowerSaveLow);
+ if (args->disabled) {
+ args->flags = 0;
+ return 0;
+ }
+
+ args->value = sme_app_value.unifi_Value_union.powerConfig.listenInterval * 1000;
+ args->flags |= IW_POWER_PERIOD;
+
+ if (sme_app_value.unifi_Value_union.powerConfig.rxDtims) {
+ args->flags |= IW_POWER_ALL_R;
+ } else {
+ args->flags |= IW_POWER_UNICAST_R;
+ }
+
+ return 0;
+} /* unifi_giwpower() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwcommit - handler for SIOCSIWCOMMIT
+ *
+ * Apply all the parameters that have been set.
+ * In practice this means:
+ * - do a scan
+ * - join a network or start an AdHoc
+ * - authenticate and associate.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwcommit(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return 0;
+} /* unifi_siwcommit() */
+
+
+
+static int
+unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+
+ CHECK_INITED(priv);
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ case IW_MLME_DISASSOC:
+ sme_mgt_disconnect(priv);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+} /* unifi_siwmlme() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwgenie
+ * unifi_giwgenie
+ *
+ * WPA : Generic IEEE 802.11 information element (e.g., for WPA/RSN/WMM).
+ * Handlers for SIOCSIWGENIE, SIOCGIWGENIE - set/get generic IE
+ *
+ * The host program (e.g. wpa_supplicant) uses this call to set the
+ * additional IEs to accompany the next (Associate?) request.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * Notes:
+ * From wireless.h:
+ * This ioctl uses struct iw_point and data buffer that includes IE id
+ * and len fields. More than one IE may be included in the
+ * request. Setting the generic IE to empty buffer (len=0) removes the
+ * generic IE from the driver.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ unifi_DataBlock *assoc_req_ie;
+ int len;
+
+ func_enter();
+
+ /* Convenience pointer */
+ assoc_req_ie = &priv->connection_config.mlmeAssociateReqInformationElements;
+
+ if (assoc_req_ie->data) {
+ kfree(assoc_req_ie->data);
+ }
+ assoc_req_ie->length = 0;
+ assoc_req_ie->data = NULL;
+
+ len = wrqu->data.length;
+ if (len == 0) {
+ func_exit();
+ return 0;
+ }
+
+ assoc_req_ie->data = kmalloc(len, GFP_KERNEL);
+ if (assoc_req_ie->data == NULL) {
+ func_exit();
+ return -ENOMEM;
+ }
+
+ assoc_req_ie->length = len;
+ memcpy(assoc_req_ie->data, extra, len);
+
+ func_exit();
+ return 0;
+} /* unifi_siwgenie() */
+
+
+static int
+unifi_giwgenie(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ int len;
+
+ func_enter();
+
+ len = priv->connection_config.mlmeAssociateReqInformationElements.length;
+
+ if (len == 0) {
+ wrqu->data.length = 0;
+ return 0;
+ }
+
+ if (wrqu->data.length < len) {
+ return -E2BIG;
+ }
+
+ wrqu->data.length = len;
+ memcpy(extra, priv->connection_config.mlmeAssociateReqInformationElements.data, len);
+
+ func_exit();
+ return 0;
+} /* unifi_giwgenie() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwauth
+ * unifi_giwauth
+ *
+ * Handlers for SIOCSIWAUTH, SIOCGIWAUTH
+ * Set/get various authentication parameters.
+ *
+ * Arguments:
+ *
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+_unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ func_enter();
+
+ /*
+ * This ioctl is safe to call even when UniFi is powered off.
+ * wpa_supplicant calls it to test whether we support WPA.
+ */
+
+ switch (wrqu->param.flags & IW_AUTH_INDEX) {
+
+ case IW_AUTH_WPA_ENABLED:
+ unifi_trace(priv, UDBG1, "IW_AUTH_WPA_ENABLED: %d\n", wrqu->param.value);
+
+ if (wrqu->param.value == 0) {
+ unifi_trace(priv, UDBG5, "IW_AUTH_WPA_ENABLED: unifi_80211_AuthOpen\n");
+ priv->connection_config.authMode = unifi_80211_AuthOpen;
+ }
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ unifi_trace(priv, UDBG1, "IW_AUTH_PRIVACY_INVOKED: %d\n", wrqu->param.value);
+
+ priv->connection_config.privacyMode = wrqu->param.value ? unifi_80211_PrivacyEnabled : unifi_80211_PrivacyDisabled;
+ if (wrqu->param.value == unifi_80211_PrivacyDisabled)
+ {
+ priv->connection_config.encryptionMode = unifi_EncryptionCipherNone;
+ }
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ switch (wrqu->param.value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM :
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_OPEN_SYSTEM)\n", wrqu->param.value);
+ priv->connection_config.authMode = unifi_80211_AuthOpen;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY :
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_SHARED_KEY)\n", wrqu->param.value);
+ priv->connection_config.authMode = unifi_80211_AuthShared;
+ break;
+ case IW_AUTH_ALG_LEAP :
+ /* Initial exchanges using open-system to set EAP */
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_LEAP)\n", wrqu->param.value);
+ priv->connection_config.authMode = unifi_8021x_AuthOther1x;
+ break;
+ default:
+ unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: invalid value %d\n",
+ wrqu->param.value);
+ return -EINVAL;
+ }
+ break;
+
+ case IW_AUTH_WPA_VERSION:
+ unifi_trace(priv, UDBG1, "IW_AUTH_WPA_VERSION: %d\n", wrqu->param.value);
+ priv->ignore_bssid_join = TRUE;
+ /*
+ IW_AUTH_WPA_VERSION_DISABLED 0x00000001
+ IW_AUTH_WPA_VERSION_WPA 0x00000002
+ IW_AUTH_WPA_VERSION_WPA2 0x00000004
+ */
+
+ if (!(wrqu->param.value & IW_AUTH_WPA_VERSION_DISABLED)) {
+
+ priv->connection_config.authMode = unifi_80211_AuthOpen;
+
+ if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA) {
+ unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA, WPA-PSK\n");
+ priv->connection_config.authMode |= (unifi_8021x_AuthWPA | unifi_8021x_AuthWPAPSK);
+ }
+ if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA2) {
+ unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA2, WPA2-PSK\n");
+ priv->connection_config.authMode |= (unifi_8021x_AuthWPA2 | unifi_8021x_AuthWPA2PSK);
+ }
+ }
+ break;
+
+ case IW_AUTH_CIPHER_PAIRWISE:
+ unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_PAIRWISE: %d\n", wrqu->param.value);
+ /*
+ * one of:
+ IW_AUTH_CIPHER_NONE 0x00000001
+ IW_AUTH_CIPHER_WEP40 0x00000002
+ IW_AUTH_CIPHER_TKIP 0x00000004
+ IW_AUTH_CIPHER_CCMP 0x00000008
+ IW_AUTH_CIPHER_WEP104 0x00000010
+ */
+
+ priv->connection_config.encryptionMode = unifi_EncryptionCipherNone;
+
+ if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
+ priv->connection_config.encryptionMode |=
+ unifi_EncryptionCipherPairwiseWep40 | unifi_EncryptionCipherGroupWep40;
+ }
+ if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
+ priv->connection_config.encryptionMode |=
+ unifi_EncryptionCipherPairwiseWep104 | unifi_EncryptionCipherGroupWep104;
+ }
+ if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
+ priv->connection_config.encryptionMode |=
+ unifi_EncryptionCipherPairwiseTkip | unifi_EncryptionCipherGroupTkip;
+ }
+ if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
+ priv->connection_config.encryptionMode |=
+ unifi_EncryptionCipherPairwiseCcmp | unifi_EncryptionCipherGroupCcmp;
+ }
+
+ break;
+
+ case IW_AUTH_CIPHER_GROUP:
+ unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_GROUP: %d\n", wrqu->param.value);
+ /*
+ * Use the WPA version and the group cipher suite to set the permitted
+ * group key in the MIB. f/w uses this value to validate WPA and RSN IEs
+ * in the probe responses from the desired BSS(ID)
+ */
+
+ priv->connection_config.encryptionMode &= ~(unifi_EncryptionCipherGroupWep40 |
+ unifi_EncryptionCipherGroupWep104 |
+ unifi_EncryptionCipherGroupTkip |
+ unifi_EncryptionCipherGroupCcmp);
+ if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
+ priv->connection_config.encryptionMode |= unifi_EncryptionCipherGroupWep40;
+ }
+ if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
+ priv->connection_config.encryptionMode |= unifi_EncryptionCipherGroupWep104;
+ }
+ if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
+ priv->connection_config.encryptionMode |= unifi_EncryptionCipherGroupTkip;
+ }
+ if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
+ priv->connection_config.encryptionMode |= unifi_EncryptionCipherGroupCcmp;
+ }
+
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ unifi_trace(priv, UDBG1, "IW_AUTH_KEY_MGMT: %d\n", wrqu->param.value);
+ /*
+ IW_AUTH_KEY_MGMT_802_1X 1
+ IW_AUTH_KEY_MGMT_PSK 2
+ */
+ if (priv->connection_config.authMode & (unifi_8021x_AuthWPA | unifi_8021x_AuthWPAPSK)) {
+ /* Check for explicitly set mode. */
+ if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
+ priv->connection_config.authMode &= ~unifi_8021x_AuthWPAPSK;
+ }
+ if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
+ priv->connection_config.authMode &= ~unifi_8021x_AuthWPA;
+ }
+ unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA: %d\n",
+ priv->connection_config.authMode);
+ }
+ if (priv->connection_config.authMode & (unifi_8021x_AuthWPA2 | unifi_8021x_AuthWPA2PSK)) {
+ /* Check for explicitly set mode. */
+ if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
+ priv->connection_config.authMode &= ~unifi_8021x_AuthWPA2PSK;
+ }
+ if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
+ priv->connection_config.authMode &= ~unifi_8021x_AuthWPA2;
+ }
+ unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA2: %d\n",
+ priv->connection_config.authMode);
+ }
+
+ break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ /*
+ * Set to true at the start of the 60 second backup-off period
+ * following 2 MichaelMIC failures within 60s.
+ */
+ unifi_trace(priv, UDBG1, "IW_AUTH_TKIP_COUNTERMEASURES: %d\n", wrqu->param.value);
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ /*
+ * Set to true on init.
+ * Set to false just before associate if encryption will not be
+ * required.
+ *
+ * Note this is not the same as the 802.1X controlled port
+ */
+ unifi_trace(priv, UDBG1, "IW_AUTH_DROP_UNENCRYPTED: %d\n", wrqu->param.value);
+ /* TODO: Anything to do here? */
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ /*
+ * This is set by wpa_supplicant to allow unencrypted EAPOL messages
+ * even if pairwise keys are set when not using WPA. IEEE 802.1X
+ * specifies that these frames are not encrypted, but WPA encrypts
+ * them when pairwise keys are in use.
+ * I think the UniFi f/w handles this decision for us.
+ */
+ unifi_trace(priv, UDBG1, "IW_AUTH_RX_UNENCRYPTED_EAPOL: %d\n", wrqu->param.value);
+ break;
+
+ case IW_AUTH_ROAMING_CONTROL:
+ unifi_trace(priv, UDBG1, "IW_AUTH_ROAMING_CONTROL: %d\n", wrqu->param.value);
+ break;
+
+ default:
+ unifi_trace(priv, UDBG1, "Unsupported auth param %d to 0x%X\n",
+ wrqu->param.flags & IW_AUTH_INDEX,
+ wrqu->param.value);
+ return -EOPNOTSUPP;
+ }
+
+ func_exit();
+
+ return 0;
+} /* _unifi_siwauth() */
+
+
+static int
+unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int err = 0;
+
+ err = _unifi_siwauth(dev, info, wrqu, extra);
+
+ return err;
+} /* unifi_siwauth() */
+
+
+static int
+unifi_giwauth(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return -EOPNOTSUPP;
+} /* unifi_giwauth() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwencodeext
+ * unifi_giwencodeext
+ *
+ * Handlers for SIOCSIWENCODEEXT, SIOCGIWENCODEEXT - set/get
+ * encoding token & mode
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * For WPA/WPA2 we don't take note of the IW_ENCODE_EXT_SET_TX_KEY flag.
+ * This flag means "use this key to encode transmissions"; we just
+ * assume only one key will be set and that is the one to use.
+ * ---------------------------------------------------------------------------
+ */
+static int
+_unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int r = 0;
+ unsigned char *keydata;
+ unsigned char tkip_key[32];
+ int keyid;
+ unsigned char *a = (unsigned char *)ext->addr.sa_data;
+ unifi_Key sme_key;
+ unifi_KeyType key_type;
+
+ func_enter();
+
+ CHECK_INITED(priv);
+
+ unifi_trace(priv, UDBG1, "siwencodeext: flags=0x%X, alg=%d, ext_flags=0x%X, len=%d, index=%d,\n",
+ wrqu->encoding.flags, ext->alg, ext->ext_flags,
+ ext->key_len, (wrqu->encoding.flags & IW_ENCODE_INDEX));
+ unifi_trace(priv, UDBG3, " addr=%02X:%02X:%02X:%02X:%02X:%02X\n",
+ a[0], a[1], a[2], a[3], a[4], a[5]);
+
+ if ((ext->key_len == 0) && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
+ /* This means use a different key (given by key_idx) for Tx. */
+ /* NYI */
+ unifi_trace(priv, UDBG1, KERN_ERR "unifi_siwencodeext: NYI should change tx key id here!!\n");
+ return -ENOTSUPP;
+ }
+
+ keydata = (unsigned char *)(ext + 1);
+ keyid = (wrqu->encoding.flags & IW_ENCODE_INDEX);
+
+ /*
+ * Check for request to delete keys for an address.
+ */
+ /* Pick out request for no privacy. */
+ if (ext->alg == IW_ENCODE_ALG_NONE) {
+
+ unifi_trace(priv, UDBG1, "Deleting %s key %d\n",
+ (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ? "GROUP" : "PAIRWISE",
+ keyid);
+
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ sme_key.keyType = unifi_GroupKey;
+ } else {
+ sme_key.keyType = unifi_PairwiseKey;
+ }
+ sme_key.keyIndex = (keyid - 1);
+ sme_key.keyLength = 0;
+ sme_key.authenticator = 0;
+ memcpy(sme_key.address.data, a, ETH_ALEN);
+
+ r = sme_mgt_key(priv, &sme_key, unifi_ListActionRemove);
+ if (r) {
+ unifi_error(priv, "Delete key request was rejected with result %d", r);
+ return r;
+ }
+
+ return 0;
+ }
+
+
+ /*
+ * Request is to set a key, not delete
+ */
+
+ /* Pick out WEP and use set_wep_key(). */
+ if (ext->alg == IW_ENCODE_ALG_WEP) {
+ /* WEP-40, WEP-104 */
+
+ /* Check for valid key length */
+ if (!((ext->key_len == 5) || (ext->key_len == 13))) {
+ unifi_trace(priv, UDBG1, KERN_ERR "Invalid length for WEP key: %d\n", ext->key_len);
+ return -EINVAL;
+ }
+
+ unifi_trace(priv, UDBG1, "Setting WEP key %d tx:%d\n",
+ keyid, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY);
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ sme_key.wepTxKey = TRUE;
+ sme_key.keyType = unifi_PairwiseKey;
+ } else {
+ sme_key.wepTxKey = FALSE;
+ sme_key.keyType = unifi_GroupKey;
+ }
+ sme_key.keyIndex = (keyid - 1);
+ sme_key.keyLength = ext->key_len;
+ sme_key.authenticator = 0;
+ memset(sme_key.address.data, 0xFF, ETH_ALEN);
+ memcpy(sme_key.key, keydata, ext->key_len);
+
+ r = sme_mgt_key(priv, &sme_key, unifi_ListActionAdd);
+ if (r) {
+ unifi_error(priv, "siwencodeext: Set key failed (%d)", r);
+ return r;
+ }
+
+ return 0;
+ }
+
+ /*
+ *
+ * If we reach here, we are dealing with a WPA/WPA2 key
+ *
+ */
+ if (ext->key_len > 32) {
+ return -EINVAL;
+ }
+
+ /*
+ * TKIP keys from wpa_supplicant need swapping.
+ * What about other supplicants (when they come along)?
+ */
+ if ((ext->alg == IW_ENCODE_ALG_TKIP) && (ext->key_len == 32)) {
+ memcpy(tkip_key, keydata, 16);
+ memcpy(tkip_key + 16, keydata + 24, 8);
+ memcpy(tkip_key + 24, keydata + 16, 8);
+ keydata = tkip_key;
+ }
+
+ key_type = (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ?
+ unifi_GroupKey : /* Group Key */
+ unifi_PairwiseKey; /* Pairwise Key */
+
+ sme_key.keyType = key_type;
+ sme_key.keyIndex = (keyid - 1);
+ sme_key.keyLength = ext->key_len;
+ sme_key.authenticator = 0;
+ memcpy(sme_key.address.data, ext->addr.sa_data, ETH_ALEN);
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ memcpy((u8*)(&sme_key.keyRsc), ext->rx_seq, 8);
+ } else {
+ memset((u8*)(&sme_key.keyRsc), 0, 8);
+ }
+ memcpy(sme_key.key, keydata, ext->key_len);
+
+ r = sme_mgt_key(priv, &sme_key, unifi_ListActionAdd);
+ if (r) {
+ unifi_error(priv, "SETKEYS request was rejected with result %d\n", r);
+ return -EIO;
+ }
+
+ func_exit();
+ return r;
+} /* _unifi_siwencodeext() */
+
+
+static int
+unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int err = 0;
+
+ err = _unifi_siwencodeext(dev, info, wrqu, extra);
+
+ return err;
+} /* unifi_siwencodeext() */
+
+
+static int
+unifi_giwencodeext(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ return -EOPNOTSUPP;
+} /* unifi_giwencodeext() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_siwpmksa
+ *
+ * SIOCSIWPMKSA - PMKSA cache operation
+ * The caller passes a pmksa structure:
+ * - cmd one of ADD, REMOVE, FLUSH
+ * - bssid MAC address
+ * - pmkid ID string (16 bytes)
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * This is not needed since we provide a siwgenie method.
+ * ---------------------------------------------------------------------------
+ */
+static int
+unifi_siwpmksa(struct net_device *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ unifi_priv_t *priv = dev->priv;
+ struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
+ unifi_Status r = 0;
+ unifi_PmkidList pmkid_list;
+ unifi_Pmkid pmkid;
+ unifi_ListAction action;
+
+ CHECK_INITED(priv);
+
+ unifi_trace(priv, UDBG1, "SIWPMKSA: cmd %d, %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pmksa->cmd,
+ pmksa->bssid.sa_data[0],
+ pmksa->bssid.sa_data[1],
+ pmksa->bssid.sa_data[2],
+ pmksa->bssid.sa_data[3],
+ pmksa->bssid.sa_data[4],
+ pmksa->bssid.sa_data[5]);
+
+ pmkid_list.pmkids = NULL;
+ switch (pmksa->cmd) {
+ case IW_PMKSA_ADD:
+ pmkid_list.pmkids = &pmkid;
+ action = unifi_ListActionAdd;
+ pmkid_list.numElements = 1;
+ memcpy(pmkid.bssid.data, pmksa->bssid.sa_data, ETH_ALEN);
+ memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
+ break;
+ case IW_PMKSA_REMOVE:
+ pmkid_list.pmkids = &pmkid;
+ action = unifi_ListActionRemove;
+ pmkid_list.numElements = 1;
+ memcpy(pmkid.bssid.data, pmksa->bssid.sa_data, ETH_ALEN);
+ memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
+ break;
+ case IW_PMKSA_FLUSH:
+ /* Replace current PMKID's with an empty list */
+ pmkid_list.numElements = 0;
+ action = unifi_ListActionFlush;
+ break;
+ default:
+ unifi_notice(priv, "SIWPMKSA: Unknown command (0x%x)\n", pmksa->cmd);
+ return -EINVAL;
+ }
+
+ /* Set the Value the pmkid's will have 1 added OR 1 removed OR be cleared at this point */
+ r = sme_mgt_pmkid(priv, action, &pmkid_list);
+ if (r) {
+ unifi_error(priv, "SIWPMKSA: Set PMKID's Failed.\n");
+ }
+
+ return r;
+
+} /* unifi_siwpmksa() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_get_wireless_stats
+ *
+ * get_wireless_stats method for Linux wireless extensions.
+ *
+ * Arguments:
+ * dev Pointer to associated netdevice.
+ *
+ * Returns:
+ * Pointer to iw_statistics struct.
+ * ---------------------------------------------------------------------------
+ */
+struct iw_statistics *
+unifi_get_wireless_stats(struct net_device *dev)
+{
+ unifi_priv_t *priv = dev->priv;
+
+ if (priv->init_progress != UNIFI_INIT_COMPLETED) {
+ return NULL;
+ }
+
+ return &priv->wext_wireless_stats;
+} /* unifi_get_wireless_stats() */
+
+
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+static const struct iw_priv_args unifi_private_args[] = {
+/*{ cmd, set_args, get_args, name } */
+ { SIOCIWS80211POWERSAVEPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_NONE, "iwprivs80211ps" },
+ { SIOCIWG80211POWERSAVEPRIV, IW_PRIV_TYPE_NONE,
+ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IWPRIV_POWER_SAVE_MAX_STRING, "iwprivg80211ps" },
+ { SIOCIWS80211RELOADDEFAULTSPRIV, IW_PRIV_TYPE_NONE,
+ IW_PRIV_TYPE_NONE, "iwprivsdefs" },
+ { SIOCIWSSMEDEBUGDUMPPRIV, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_NONE, "iwprivssmedump" },
+};
+
+static const iw_handler unifi_handler[] =
+{
+ (iw_handler) unifi_siwcommit, /* SIOCSIWCOMMIT */
+ (iw_handler) unifi_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) unifi_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) unifi_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) unifi_siwmode, /* SIOCSIWMODE */
+ (iw_handler) unifi_giwmode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL, /* SIOCSIWRANGE */
+ (iw_handler) unifi_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) NULL, /* SIOCSIWPRIV */
+ (iw_handler) NULL, /* SIOCGIWPRIV */
+ (iw_handler) NULL, /* SIOCSIWSTATS */
+ (iw_handler) NULL, /* SIOCGIWSTATS */
+#if 0
+ iw_handler_set_spy, /* SIOCSIWSPY */
+ iw_handler_get_spy, /* SIOCGIWSPY */
+ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
+ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
+#else
+ (iw_handler) NULL, /* SIOCSIWSPY */
+ (iw_handler) NULL, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* SIOCSIWTHRSPY */
+ (iw_handler) NULL, /* SIOCGIWTHRSPY */
+#endif
+ (iw_handler) unifi_siwap, /* SIOCSIWAP */
+ (iw_handler) unifi_giwap, /* SIOCGIWAP */
+#if WIRELESS_EXT > 17
+ /* WPA : IEEE 802.11 MLME requests */
+ unifi_siwmlme, /* SIOCSIWMLME, request MLME operation */
+#else
+ (iw_handler) NULL, /* -- hole -- */
+#endif
+ (iw_handler) NULL, /* SIOCGIWAPLIST */
+ (iw_handler) unifi_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) unifi_giwscan, /* SIOCGIWSCAN */
+ (iw_handler) unifi_siwessid, /* SIOCSIWESSID */
+ (iw_handler) unifi_giwessid, /* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) NULL, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ unifi_siwrate, /* SIOCSIWRATE */
+ unifi_giwrate, /* SIOCGIWRATE */
+ unifi_siwrts, /* SIOCSIWRTS */
+ unifi_giwrts, /* SIOCGIWRTS */
+ unifi_siwfrag, /* SIOCSIWFRAG */
+ unifi_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) NULL, /* SIOCSIWTXPOW */
+ (iw_handler) NULL, /* SIOCGIWTXPOW */
+ (iw_handler) NULL, /* SIOCSIWRETRY */
+ (iw_handler) NULL, /* SIOCGIWRETRY */
+ unifi_siwencode, /* SIOCSIWENCODE */
+ unifi_giwencode, /* SIOCGIWENCODE */
+ unifi_siwpower, /* SIOCSIWPOWER */
+ unifi_giwpower, /* SIOCGIWPOWER */
+#if WIRELESS_EXT > 17
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+
+ /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). */
+ unifi_siwgenie, /* SIOCSIWGENIE */ /* set generic IE */
+ unifi_giwgenie, /* SIOCGIWGENIE */ /* get generic IE */
+
+ /* WPA : Authentication mode parameters */
+ unifi_siwauth, /* SIOCSIWAUTH */ /* set authentication mode params */
+ unifi_giwauth, /* SIOCGIWAUTH */ /* get authentication mode params */
+
+ /* WPA : Extended version of encoding configuration */
+ unifi_siwencodeext, /* SIOCSIWENCODEEXT */ /* set encoding token & mode */
+ unifi_giwencodeext, /* SIOCGIWENCODEEXT */ /* get encoding token & mode */
+
+ /* WPA2 : PMKSA cache management */
+ unifi_siwpmksa, /* SIOCSIWPMKSA */ /* PMKSA cache operation */
+ (iw_handler) NULL, /* -- hole -- */
+#endif /* WIRELESS_EXT > 17 */
+};
+
+
+static const iw_handler unifi_private_handler[] =
+{
+ iwprivs80211ps,
+ iwprivg80211ps,
+ iwprivsdefs,
+ iwprivssmedebugdump,
+};
+
+struct iw_handler_def unifi_iw_handler_def =
+{
+ .num_standard = sizeof(unifi_handler) / sizeof(iw_handler),
+ .num_private = sizeof(unifi_private_handler) / sizeof(iw_handler),
+ .num_private_args = sizeof(unifi_private_args) / sizeof(struct iw_priv_args),
+ .standard = (iw_handler *) unifi_handler,
+ .private = (iw_handler *) unifi_private_handler,
+ .private_args = (struct iw_priv_args *) unifi_private_args,
+#if IW_HANDLER_VERSION >= 6
+ .get_wireless_stats = unifi_get_wireless_stats,
+#endif
+#if 0
+ .spy_offset = ((void *) (&((struct unifi_info *) NULL)->spy_data) -
+ (void *) NULL),
+#endif
+};
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/ul_int.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/ul_int.c
new file mode 100644
index 0000000..7623d9a
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/ul_int.c
@@ -0,0 +1,553 @@
+/*
+ * ***************************************************************************
+ * FILE: ul_int.c
+ *
+ * PURPOSE:
+ * Manage list of client applications using UniFi.
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include "driver/unifi.h"
+#include "driver/conversions.h"
+#include "unifi_priv.h"
+#include "unifiio.h"
+
+/* The start of the range of process ids allocated for ul clients */
+#define UDI_SENDER_ID_BASE 0xC000
+#define UDI_SENDER_ID_SHIFT 8
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ul_init_clients
+ *
+ * Initialise the clients array to empty.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * This function needs to be called before priv is stored in
+ * Unifi_instances[].
+ * ---------------------------------------------------------------------------
+ */
+void
+ul_init_clients(unifi_priv_t *priv)
+{
+ int id;
+ ul_client_t *ul_clients;
+
+ init_MUTEX(&priv->udi_logging_mutex);
+ priv->logging_client = NULL;
+
+ ul_clients = priv->ul_clients;
+
+ for (id = 0; id < MAX_UDI_CLIENTS; id++) {
+ memset(&ul_clients[id], 0, sizeof(ul_client_t));
+
+ ul_clients[id].client_id = id;
+ ul_clients[id].sender_id = UDI_SENDER_ID_BASE + (id << UDI_SENDER_ID_SHIFT);
+ ul_clients[id].instance = -1;
+ ul_clients[id].event_hook = NULL;
+
+ INIT_LIST_HEAD(&ul_clients[id].udi_log);
+ init_waitqueue_head(&ul_clients[id].udi_wq);
+ sema_init(&ul_clients[id].udi_sem, 1);
+
+ ul_clients[id].wake_up_wq_id = 0;
+ ul_clients[id].seq_no = 0;
+ ul_clients[id].wake_seq_no = 0;
+ ul_clients[id].snap_filter.count = 0;
+ }
+} /* ul_init_clients() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ul_register_client
+ *
+ * This function registers a new ul client.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * configuration Special configuration for the client.
+ * udi_event_clbk Callback for receiving event from unifi.
+ *
+ * Returns:
+ * 0 if a new clients is registered, -1 otherwise.
+ * ---------------------------------------------------------------------------
+ */
+ul_client_t *
+ul_register_client(unifi_priv_t *priv, unsigned int configuration,
+ udi_event_t udi_event_clbk)
+{
+ unsigned char id, ref;
+ ul_client_t *ul_clients;
+
+ ul_clients = priv->ul_clients;
+
+ /* check for an unused entry */
+ for (id = 0; id < MAX_UDI_CLIENTS; id++) {
+ if (ul_clients[id].udi_enabled == 0) {
+ ul_clients[id].instance = priv->instance;
+ ul_clients[id].udi_enabled = 1;
+ ul_clients[id].configuration = configuration;
+
+ /* Allocate memory for the reply signal.. */
+ ul_clients[id].reply_signal = (CSR_SIGNAL*) unifi_malloc(priv, sizeof(CSR_SIGNAL));
+ if (ul_clients[id].reply_signal == NULL) {
+ unifi_error(priv, "Failed to allocate reply signal for client.\n");
+ return NULL;
+ }
+ /* .. and the bulk data of the reply signal. */
+ for (ref = 0; ref < UNIFI_MAX_DATA_REFERENCES; ref ++) {
+ ul_clients[id].reply_bulkdata[ref] =
+ (bulk_data_t*) unifi_malloc(priv, sizeof(bulk_data_t));
+ /* If allocation fails, free allocated memory. */
+ if (ul_clients[id].reply_bulkdata[ref] == NULL) {
+ for (; ref > 0; ref --) {
+ unifi_free(priv, ul_clients[id].reply_bulkdata[ref - 1]);
+ }
+ unifi_free(priv, ul_clients[id].reply_signal);
+ unifi_error(priv, "Failed to allocate bulk data buffers for client.\n");
+ return NULL;
+ }
+ }
+
+ /* Set the event callback. */
+ ul_clients[id].event_hook = udi_event_clbk;
+
+ unifi_trace(priv, UDBG2, "UDI %d (0x%x) registered. configuration = 0x%x\n",
+ id, &ul_clients[id], configuration);
+ return &ul_clients[id];
+ }
+ }
+ return NULL;
+} /* ul_register_client() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ul_deregister_client
+ *
+ * This function deregisters a blocking UDI client.
+ *
+ * Arguments:
+ * client Pointer to the client we deregister.
+ *
+ * Returns:
+ * 0 if a new clients is deregistered.
+ * ---------------------------------------------------------------------------
+ */
+int
+ul_deregister_client(ul_client_t *ul_client)
+{
+ struct list_head *pos, *n;
+ udi_log_t *logptr;
+ unifi_priv_t *priv = unifi_find_instance(ul_client->instance);
+ int ref;
+
+ ul_client->instance = -1;
+ ul_client->event_hook = NULL;
+ ul_client->udi_enabled = 0;
+ unifi_trace(priv, UDBG5, "UDI (0x%x) deregistered.\n", ul_client);
+
+ /* Free memory allocated for the reply signal and its bulk data. */
+ unifi_free(priv, ul_client->reply_signal);
+ for (ref = 0; ref < UNIFI_MAX_DATA_REFERENCES; ref ++) {
+ unifi_free(priv, ul_client->reply_bulkdata[ref]);
+ }
+
+ if (ul_client->snap_filter.count) {
+ ul_client->snap_filter.count = 0;
+ unifi_free(priv, ul_client->snap_filter.protocols);
+ }
+
+ /* Free anything pending on the udi_log list */
+ down(&ul_client->udi_sem);
+ list_for_each_safe(pos, n, &ul_client->udi_log)
+ {
+ logptr = list_entry(pos, udi_log_t, q);
+ list_del(pos);
+ kfree(logptr);
+ }
+ up(&ul_client->udi_sem);
+
+ return 0;
+} /* ul_deregister_client() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * logging_handler
+ *
+ * This function is registered with the driver core.
+ * It is called every time a UniFi HIP Signal is sent. It iterates over
+ * the list of processes interested in receiving log events and
+ * delivers the events to them.
+ *
+ * Arguments:
+ * ospriv Pointer to driver's private data.
+ * sigdata Pointer to the packed signal buffer.
+ * signal_len Length of the packed signal.
+ * bulkdata Pointer to the signal's bulk data.
+ * dir Direction of the signal
+ * 0 = from-host
+ * 1 = to-host
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+logging_handler(void *ospriv, unsigned char *sigdata, int signal_len,
+ const bulk_data_param_t *bulkdata, enum udi_log_direction direction)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+ ul_client_t *client;
+ int dir;
+
+ dir = (direction == UDI_LOG_FROM_HOST) ? UDI_FROM_HOST : UDI_TO_HOST;
+
+ down(&priv->udi_logging_mutex);
+ client = priv->logging_client;
+ if (client != NULL) {
+ client->event_hook(client, sigdata, signal_len,
+ bulkdata, dir);
+ }
+ up(&priv->udi_logging_mutex);
+
+} /* logging_handler() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * send_client
+ *
+ * Helper for unifi_receive_event.
+ *
+ * This function forwards a signal to one client.
+ *
+ * Arguments:
+ * priv Pointer to driver's private data.
+ * client Pointer to the client structure.
+ * receiver_id The reciever id of the signal.
+ * sigdata Pointer to the packed signal buffer.
+ * siglen Length of the packed signal.
+ * bulkdata Pointer to the signal's bulk data.
+ *
+ * Returns:
+ * None.
+ *
+ * ---------------------------------------------------------------------------
+ */
+static void send_to_client(unifi_priv_t *priv, ul_client_t *client,
+ int receiver_id,
+ unsigned char *sigdata, int siglen,
+ const bulk_data_param_t *bulkdata)
+{
+ if (client && client->event_hook) {
+ unifi_trace(priv, UDBG3,
+ "Receive: client %d, (s:0x%X, r:0x%X) - Signal %s \n",
+ client->client_id, client->sender_id, receiver_id,
+ lookup_signal_name(UNPACK16((sigdata), 0)));
+
+ client->event_hook(client, sigdata, siglen, bulkdata, UDI_TO_HOST);
+ }
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * unifi_receive_event
+ *
+ * Dispatcher for received signals.
+ *
+ * This function receives the 'to host' signals and forwards
+ * them to the unifi linux clients.
+ *
+ * Arguments:
+ * ospriv Pointer to driver's private data.
+ * sigdata Pointer to the packed signal buffer.
+ * siglen Length of the packed signal.
+ * bulkdata Pointer to the signal's bulk data.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * The signals are received in the format described in the host interface
+ * specification, i.e wire formatted. Certain clients use the same format
+ * to interpret them and other clients use the host formatted structures.
+ * Each client has to call read_unpack_signal() to transform the wire
+ * formatted signal into the host formatted signal, if necessary.
+ * The code is in the core, since the signals are defined therefore
+ * binded to the host interface specification.
+ * ---------------------------------------------------------------------------
+ */
+void
+unifi_receive_event(void *ospriv,
+ unsigned char *sigdata, int siglen,
+ const bulk_data_param_t *bulkdata)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+ int i, receiver_id;
+ int client_id;
+ int16 signal_id;
+
+ func_enter();
+
+ unifi_trace(priv, UDBG5, "unifi_receive_event: "
+ "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
+ UNPACK16((sigdata), sizeof(int16)*0) & 0xFFFF,
+ UNPACK16((sigdata), sizeof(int16)*1) & 0xFFFF,
+ UNPACK16((sigdata), sizeof(int16)*2) & 0xFFFF,
+ UNPACK16((sigdata), sizeof(int16)*3) & 0xFFFF,
+ UNPACK16((sigdata), sizeof(int16)*4) & 0xFFFF,
+ UNPACK16((sigdata), sizeof(int16)*5) & 0xFFFF,
+ UNPACK16((sigdata), sizeof(int16)*6) & 0xFFFF,
+ UNPACK16((sigdata), sizeof(int16)*7) & 0xFFFF, siglen);
+
+ receiver_id = UNPACK16((sigdata), sizeof(int16)) & 0xFFF0;
+ client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
+ signal_id = UNPACK16((sigdata), 0);
+
+ /* Signals with ReceiverId==0 are also reported to SME / WEXT */
+ if (receiver_id == 0) {
+
+ /*
+ * We must not pass MA.UNITDATA-INDICATIONs to the SME because
+ * we can not filter them in the handler. The reason is that we
+ * need to pass some AMP related data, but the filtering needs
+ * be done in the 802.11->802.3 translation to avoid extra process
+ * in the data path.
+ */
+ if (signal_id != CSR_MA_UNITDATA_INDICATION_ID) {
+ send_to_client(priv, priv->sme_cli,
+ receiver_id,
+ sigdata, siglen, bulkdata);
+ }
+
+#ifdef CSR_NATIVE_LINUX
+ send_to_client(priv, priv->wext_client,
+ receiver_id,
+ sigdata, siglen, bulkdata);
+#endif
+ }
+
+ if ((client_id < MAX_UDI_CLIENTS) &&
+ (&priv->ul_clients[client_id] != priv->logging_client)) {
+ send_to_client(priv, &priv->ul_clients[client_id],
+ receiver_id,
+ sigdata, siglen, bulkdata);
+ }
+
+ /*
+ * Free bulk data buffers here unless it is a CSR_MA_UNITDATA_INDICATION
+ */
+ switch (signal_id)
+ {
+ case CSR_MA_UNITDATA_INDICATION_ID:
+#ifdef UNIFI_SNIFF_ARPHRD
+ case CSR_MA_SNIFFDATA_INDICATION_ID:
+#endif
+ break;
+
+ default:
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ if (bulkdata->d[i].data_length != 0) {
+ unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
+ }
+ }
+ }
+
+ func_exit();
+} /* unifi_receive_event() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ul_log_config_ind
+ *
+ * This function uses the client's register callback
+ * to indicate configuration information e.g core errors.
+ *
+ * Arguments:
+ * priv Pointer to driver's private data.
+ * conf_param Pointer to the configuration data.
+ * len Length of the configuration data.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len)
+{
+#ifdef CSR_SUPPORT_SME
+ if (priv->smepriv == NULL)
+ {
+ return;
+ }
+ if ((CONFIG_IND_ERROR == (*conf_param)) && (priv->wifi_on_state == wifi_on_in_progress)) {
+ unifi_notice(priv, "ul_log_config_ind: wifi on in progress, suppress error\n");
+ } else {
+ /* wifi_off_ind (error or exit) */
+ unifi_sys_wifi_off_ind(priv->smepriv, (unifi_ControlIndication)(*conf_param));
+ }
+
+#else
+ bulk_data_param_t bulkdata;
+
+ /*
+ * If someone killed unifi_managed before the driver was unloaded
+ * the g_drvpriv pointer is going to be NULL. In this case it is
+ * safe to assume that there is no client to get the indication.
+ */
+ if (!priv) {
+ unifi_notice(NULL, "uf_sme_event_ind: NULL priv\n");
+ return;
+ }
+
+ /* Create a null bulkdata structure. */
+ bulkdata.d[0].data_length = 0;
+ bulkdata.d[1].data_length = 0;
+
+ sme_native_log_event(priv->sme_cli, conf_param, sizeof(uint8),
+ &bulkdata, UDI_CONFIG_IND);
+
+#endif /* CSR_SUPPORT_SME */
+
+} /* ul_log_config_ind */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ul_send_signal_unpacked
+ *
+ * This function sends a host formatted signal to unifi.
+ *
+ * Arguments:
+ * priv Pointer to driver's private data.
+ * sigptr Pointer to the signal.
+ * bulkdata Pointer to the signal's bulk data.
+ *
+ * Returns:
+ * O on success, error code otherwise.
+ *
+ * Notes:
+ * The signals have to be sent in the format described in the host interface
+ * specification, i.e wire formatted. Certain clients use the host formatted
+ * structures. The write_pack() transforms the host formatted signal
+ * into the wired formatted signal. The code is in the core, since the signals
+ * are defined therefore binded to the host interface specification.
+ * ---------------------------------------------------------------------------
+ */
+int
+ul_send_signal_unpacked(unifi_priv_t *priv, const CSR_SIGNAL *sigptr,
+ const bulk_data_param_t *bulkdata)
+{
+ unsigned char sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
+ int r, packed_siglen;
+ unsigned long lock_flags;
+
+ r = write_pack(sigptr, sigbuf, &packed_siglen);
+ if (r) {
+ unifi_error(priv, "Malformed HIP signal in ul_send_signal_unpacked()\n");
+ return r;
+ }
+
+ spin_lock_irqsave(&priv->send_signal_lock, lock_flags);
+ r = unifi_send_signal(priv->card, sigbuf, packed_siglen, bulkdata);
+ spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
+
+ return r;
+} /* ul_send_signal_unpacked() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * reset_driver_status
+ *
+ * This function is called from ul_send_signal_raw() when it detects
+ * that the SME has sent a MLME-RESET request.
+ *
+ * Arguments:
+ * priv Pointer to device private struct
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+reset_driver_status(unifi_priv_t *priv)
+{
+ priv->sta_wmm_capabilities = 0;
+#ifdef CSR_NATIVE_LINUX
+ priv->mc_list_count_stored = 0;
+ priv->wext_conf.flag_associated = 0;
+ priv->wext_conf.block_controlled_port = unifi_8021x_PortOpen;
+ priv->wext_conf.bss_wmm_capabilities = 0;
+ priv->wext_conf.disable_join_on_ssid_set = 0;
+#endif
+} /* reset_driver_status() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * ul_send_signal_raw
+ *
+ * This function sends a wire formatted data signal to unifi.
+ *
+ * Arguments:
+ * priv Pointer to driver's private data.
+ * sigptr Pointer to the signal.
+ * siglen Length of the signal.
+ * bulkdata Pointer to the signal's bulk data.
+ *
+ * Returns:
+ * O on success, error code otherwise.
+ * ---------------------------------------------------------------------------
+ */
+int
+ul_send_signal_raw(unifi_priv_t *priv, const unsigned char *sigptr, int siglen,
+ const bulk_data_param_t *bulkdata)
+{
+ int r;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&priv->send_signal_lock, lock_flags);
+ r = unifi_send_signal(priv->card, sigptr, siglen, bulkdata);
+ spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
+
+ if (r) {
+ return r;
+ }
+
+ /*
+ * Since this is use by unicli, if we get an MLME reset request
+ * we need to initialize a few status parameters
+ * that the driver uses to make decisions.
+ */
+ if (GET_SIGNAL_ID(sigptr) == CSR_MLME_RESET_REQUEST_ID) {
+ /* TODO: do not use this */
+ reset_driver_status(priv);
+ }
+
+ return 0;
+} /* ul_send_signal_raw() */
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_clients.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_clients.h
new file mode 100644
index 0000000..8376107
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_clients.h
@@ -0,0 +1,126 @@
+/*
+ *****************************************************************************
+ *
+ * FILE : unifi_clients.h
+ *
+ * PURPOSE : Private header file for unifi clients.
+ *
+ * UDI = UniFi Debug Interface
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ *****************************************************************************
+ */
+#ifndef __LINUX_UNIFI_CLIENTS_H__
+#define __LINUX_UNIFI_CLIENTS_H__ 1
+
+#include <linux/kernel.h>
+
+#define MAX_UDI_CLIENTS 8
+
+
+/* Structure to hold a UDI logged signal */
+typedef struct {
+
+ /* List link structure */
+ struct list_head q;
+
+ /* The message that will be passed to the user app */
+ udi_msg_t msg;
+
+ /* Signal body and data follow */
+
+} udi_log_t;
+
+
+
+typedef struct ul_client ul_client_t;
+
+typedef void (*udi_event_t)(ul_client_t *client,
+ u8 *sigdata, int signal_len,
+ const bulk_data_param_t *bulkdata,
+ int dir);
+
+void logging_handler(void *ospriv,
+ unsigned char *sigdata, int signal_len,
+ const bulk_data_param_t *bulkdata,
+ enum udi_log_direction dir);
+
+
+/*
+ * Structure describing a bulk data slot.
+ * The length field is used to indicate empty/occupied state.
+ */
+typedef struct _bulk_data
+{
+ unsigned char ptr[2000];
+ unsigned int length;
+} bulk_data_t;
+
+
+struct ul_client {
+ /* Index of this client in the ul_clients array. */
+ int client_id;
+
+ /* Index of UniFi device to which this client is attached. */
+ int instance;
+
+ /* Flag to say whether this client has been enabled. */
+ int udi_enabled;
+
+ /* Value to use in signal->SenderProcessId */
+ int sender_id;
+
+ /* Configuration flags, e.g blocking, logging, etc. */
+ unsigned int configuration;
+
+ udi_event_t event_hook;
+
+ /* A list to hold signals received from UniFi for reading by read() */
+ struct list_head udi_log;
+
+ /* Semaphore to protect the udi_log list */
+ struct semaphore udi_sem;
+
+ /*
+ * Linux waitqueue to support blocking read and poll.
+ * Logging clients should wait on udi_log. while
+ * blocking clients should wait on wake_up_wq.
+ */
+ wait_queue_head_t udi_wq;
+
+ CSR_SIGNAL* reply_signal;
+ bulk_data_t* reply_bulkdata[UNIFI_MAX_DATA_REFERENCES];
+
+ uint16 signal_filter[SIG_FILTER_SIZE];
+
+
+ /* ------------------------------------------------------------------- */
+ /* Code below here is used by the sme_native configuration only */
+
+ /* Flag to wake up blocking clients waiting on udi_wq. */
+ int wake_up_wq_id;
+
+ /*
+ * A 0x00 - 0x0F mask to apply in signal->SenderProcessId.
+ * Every time we do a blocking mlme request we increase this value.
+ * The mlme_wait_for_reply() will wait for this sequence number.
+ * Only the MLME blocking functions update this field.
+ */
+ unsigned char seq_no;
+
+ /*
+ * A 0x00 - 0x0F counter, containing the sequence number of
+ * the signal that this client has last received.
+ * Only the MLME blocking functions update this field.
+ */
+ unsigned char wake_seq_no;
+
+ unifiio_snap_filter_t snap_filter;
+}; /* struct ul_client */
+
+
+#endif /* __LINUX_UNIFI_CLIENTS_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_config.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_config.h
new file mode 100644
index 0000000..d189916
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_config.h
@@ -0,0 +1,41 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: unifi_config.h
+ *
+ * PURPOSE:
+ * This header file provides parameters that configure the operation
+ * of the driver.
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __UNIFI_CONFIG_H__
+#define __UNIFI_CONFIG_H__ 1
+
+
+/*
+ * It is sometimes useful to force all bulk data transfers to be a multiple
+ * of the SDIO block size, so the SDIO driver won't try to use
+ * a byte-mode CMD53. These are broken on some hardware platforms.
+ *
+ * Define UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE to force it.
+ */
+#define UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE
+
+
+/*
+ * It is sometimes useful to force all signal transfers to be a multiple
+ * of the SDIO block size, so the SDIO driver won't try to use
+ * a byte-mode CMD53. These are broken on some hardware platforms.
+ *
+ * Define UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE to force it.
+ */
+#define UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE
+
+
+#endif /* __UNIFI_CONFIG_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_dbg.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_dbg.c
new file mode 100644
index 0000000..5e61134
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_dbg.c
@@ -0,0 +1,105 @@
+/*
+ * ***************************************************************************
+ * FILE: unifi_dbg.c
+ *
+ * PURPOSE:
+ * Handle debug signals received from UniFi.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include "unifi_priv.h"
+
+/*
+ * ---------------------------------------------------------------------------
+ * debug_string_indication
+ * debug_word16_indication
+ *
+ * Handlers for debug indications.
+ *
+ * Arguments:
+ * priv Pointer to private context structure.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+debug_string_indication(unifi_priv_t *priv, const unsigned char *extra, unsigned int extralen)
+{
+ const unsigned int maxlen = sizeof(priv->last_debug_string) - 1;
+
+ if (extralen > maxlen) {
+ extralen = maxlen;
+ }
+
+ strncpy(priv->last_debug_string, extra, extralen);
+
+ /* Make sure the string is terminated */
+ priv->last_debug_string[maxlen] = '\0';
+
+ unifi_info(priv, "unifi debug: %s\n", priv->last_debug_string);
+
+} /* debug_string_indication() */
+
+
+
+void
+debug_word16_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr)
+{
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ priv->last_debug_word16[i] =
+ sigptr->u.DebugWord16Indication.DebugWords[i];
+ }
+
+ if (priv->last_debug_word16[0] == 0xFA11) {
+ unsigned long ts;
+ ts = (priv->last_debug_word16[6] << 16) | priv->last_debug_word16[5];
+ unifi_info(priv, " %10lu: %s fault %04x, arg %04x (x%d)\n",
+ ts,
+ priv->last_debug_word16[3] == 0x8000 ? "MAC" :
+ priv->last_debug_word16[3] == 0x4000 ? "PHY" :
+ "???",
+ priv->last_debug_word16[1],
+ priv->last_debug_word16[2],
+ priv->last_debug_word16[4]);
+ }
+ else if (priv->last_debug_word16[0] != 0xDBAC)
+ /* suppress SDL Trace output (note: still available to unicli). */
+ {
+ unifi_info(priv, "unifi debug: %04X %04X %04X %04X %04X %04X %04X %04X\n",
+ priv->last_debug_word16[0], priv->last_debug_word16[1],
+ priv->last_debug_word16[2], priv->last_debug_word16[3],
+ priv->last_debug_word16[4], priv->last_debug_word16[5],
+ priv->last_debug_word16[6], priv->last_debug_word16[7]);
+ unifi_info(priv, " %04X %04X %04X %04X %04X %04X %04X %04X\n",
+ priv->last_debug_word16[8], priv->last_debug_word16[9],
+ priv->last_debug_word16[10], priv->last_debug_word16[11],
+ priv->last_debug_word16[12], priv->last_debug_word16[13],
+ priv->last_debug_word16[14], priv->last_debug_word16[15]);
+ }
+
+} /* debug_word16_indication() */
+
+
+void
+debug_generic_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr)
+{
+ unifi_info(priv, "debug: %04X %04X %04X %04X %04X %04X %04X %04X\n",
+ sigptr->u.DebugGenericIndication.DebugWords[0],
+ sigptr->u.DebugGenericIndication.DebugWords[1],
+ sigptr->u.DebugGenericIndication.DebugWords[2],
+ sigptr->u.DebugGenericIndication.DebugWords[3],
+ sigptr->u.DebugGenericIndication.DebugWords[4],
+ sigptr->u.DebugGenericIndication.DebugWords[5],
+ sigptr->u.DebugGenericIndication.DebugWords[6],
+ sigptr->u.DebugGenericIndication.DebugWords[7]);
+
+} /* debug_generic_indication() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_os.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_os.h
new file mode 100644
index 0000000..b43a552
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_os.h
@@ -0,0 +1,164 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: os_linux/unifi_os.h
+ *
+ * PURPOSE:
+ * This header file provides the OS-dependent facilities for a linux
+ * environment.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __UNIFI_OS_LINUX_H__
+#define __UNIFI_OS_LINUX_H__ 1
+
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+
+
+/*
+ * Provides the POSIX error codes:
+ * EIO operation failed
+ * ETIMEDOUT UniFi didn't respond
+ * ENODEV UniFi has goen away (e.g. ejected from SDIO slot)
+ * EINVAL Bad parameter
+ * ENOMEM Memory allocation failed.
+ * Note that the SDIO driver may also return -ETIMEDOUT to indicate
+ * that an SDIO operation failed due to a timeout error. This case
+ * is translated into -EIO in card_sdio_mem.c.
+ */
+#include <linux/errno.h>
+
+
+/*
+ * Needed for core/signals.c
+ */
+#include <stddef.h>
+
+
+/* Macro to silence warnings about unused function arguments */
+#define UNUSED(var) ((void)(var))
+
+/* Define INLINE directive*/
+#define INLINE inline
+
+/* Malloc and free */
+void *unifi_malloc(void *ospriv, unsigned int size);
+void unifi_free(void *ospriv, void *ptr);
+
+int unifi_net_data_malloc(void *ospriv, bulk_data_desc_t *bulk_data_slot, unsigned int size);
+void unifi_net_data_free(void *ospriv, bulk_data_desc_t *bulk_data_slot);
+
+/*
+ * unifi_delay_us
+ *
+ * Pause for a short period. This would typically be a busy wait.
+ */
+void unifi_delay_us(void *ospriv, unsigned long t);
+
+/*
+ * unifi_sleep_ms
+ *
+ * Pause for a longer period. This would typically be a sleep involving
+ * a deschedule.
+ */
+unsigned long unifi_sleep_ms(void *ospriv, unsigned long t);
+
+
+
+/*
+ * Byte Order
+ * Note that __le*_to_cpu and __cpu_to_le* return an unsigned value!
+ */
+#ifdef __KERNEL__
+#define unifi2host_16(n) (__le16_to_cpu((n)))
+#define unifi2host_32(n) (__le32_to_cpu((n)))
+#define host2unifi_16(n) (__cpu_to_le16((n)))
+#define host2unifi_32(n) (__cpu_to_le32((n)))
+#endif
+
+/* Module parameters */
+extern int unifi_debug;
+
+/* debugging */
+#ifdef UNIFI_DEBUG
+/*
+ * unifi_debug is a verbosity level for debug messages
+ * UDBG0 msgs are always printed if UNIFI_DEBUG is defined
+ * UDBG1 msgs are printed if UNIFI_DEBUG is defined and unifi_debug > 0
+ * etc.
+ */
+
+#define func_enter() \
+ do { \
+ if (unifi_debug >= 5) { \
+ printk("unifi: => %s\n", __FUNCTION__); \
+ } \
+ } while (0)
+#define func_exit() \
+ do { \
+ if (unifi_debug >= 5) { \
+ printk("unifi: <= %s\n", __FUNCTION__); \
+ } \
+ } while (0)
+#define func_exit_r(_rc) \
+ do { \
+ if (unifi_debug >= 5) { \
+ printk("unifi: <= %s %d\n", __FUNCTION__, (_rc)); \
+ } \
+ } while (0)
+
+
+#define ASSERT(cond) \
+do { \
+ if (!(cond)) { \
+ printk("Assertion failed in %s at %s:%d: %s\n", \
+ __FUNCTION__, __FILE__, __LINE__, #cond); \
+ } \
+} while (0)
+
+
+void dump(void *mem, int len);
+void dump16(void *mem, int len);
+
+#else
+
+#define func_enter()
+#define func_exit()
+#define func_exit_r(_rc)
+
+#define ASSERT(cond)
+
+static inline void dump(void *mem, int len) {}
+static inline void dump16(void *mem, int len) {}
+
+#endif /* UNIFI_DEBUG */
+
+
+void unifi_error(void* ospriv, const char *fmt, ...);
+void unifi_warning(void* ospriv, const char *fmt, ...);
+void unifi_notice(void* ospriv, const char *fmt, ...);
+void unifi_info(void* ospriv, const char *fmt, ...);
+
+void unifi_trace(void* ospriv, int level, const char *fmt, ...);
+
+/* Different levels of diagnostic detail... */
+#define UDBG1 1
+#define UDBG2 2
+#define UDBG3 3
+#define UDBG4 4
+#define UDBG5 5
+#define UDBG6 6
+#define UDBG7 7
+
+#define unifi_sprintf sprintf
+
+#endif /* __UNIFI_OS_LINUX_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_priv.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_priv.h
new file mode 100644
index 0000000..de98a1e
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_priv.h
@@ -0,0 +1,511 @@
+/*
+ *****************************************************************************
+ *
+ * FILE : unifi_priv.h
+ *
+ * PURPOSE : Private header file for unifi driver.
+ *
+ * UDI = UniFi Debug Interface
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ *****************************************************************************
+ */
+#ifndef __LINUX_UNIFI_PRIV_H__
+#define __LINUX_UNIFI_PRIV_H__ 1
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/cdev.h>
+#include <linux/kthread.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
+#include <linux/freezer.h>
+#endif
+
+#include <linux/fs.h>
+
+#include "driver/unifi.h"
+#include "driver/unifi_udi.h"
+
+#include "unifiio.h"
+
+/*
+ * The UniFi Linux Driver versions
+ */
+#include "os_version.h"
+
+
+/* Define the unifi_priv_t before include the unifi_native.h */
+struct unifi_priv;
+typedef struct unifi_priv unifi_priv_t;
+
+
+#ifdef CSR_SUPPORT_WEXT
+#include "unifi_wext.h"
+#endif
+
+#include "unifi_clients.h"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#include <linux/workqueue.h>
+
+#undef INIT_WORK
+#define INIT_WORK(_work, _func) \
+ do { \
+ INIT_LIST_HEAD(&(_work)->entry); \
+ (_work)->pending = 0; \
+ PREPARE_WORK((_work), (_func), (_work)); \
+ init_timer(&(_work)->timer); \
+ } while(0)
+
+#endif /* Linux kernel < 2.6.20 */
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#define UF_NETIF_TX_WAKE_ALL_QUEUES(_netdev) netif_tx_wake_all_queues(_netdev)
+#define UF_NETIF_TX_START_ALL_QUEUES(_netdev) netif_tx_start_all_queues(_netdev)
+#define UF_NETIF_TX_STOP_ALL_QUEUES(_netdev) netif_tx_stop_all_queues(_netdev)
+#else
+#define UF_NETIF_TX_WAKE_ALL_QUEUES(_netdev) netif_wake_queue(_netdev)
+#define UF_NETIF_TX_START_ALL_QUEUES(_netdev) netif_start_queue(_netdev)
+#define UF_NETIF_TX_STOP_ALL_QUEUES(_netdev) netif_stop_queue(_netdev)
+#endif
+
+
+#ifdef CSR_NATIVE_LINUX
+#include "sme_native/unifi_native.h"
+#else
+#include "unifi_sme.h"
+#endif
+
+/* The device major number to use when registering the udi driver */
+#define UNIFI_NAME "unifi"
+#define MAX_UNIFI_DEVS 2
+
+
+/* Module parameter variables */
+extern int buswidth;
+extern int sdio_clock;
+extern int use_5g;
+extern int disable_hw_reset;
+extern int sme_debug;
+extern int fw_init[MAX_UNIFI_DEVS];
+extern int tl_80211d;
+
+struct dlpriv {
+ unsigned char *dl_data;
+ int dl_len;
+};
+
+
+struct uf_thread {
+
+ struct task_struct *thread_task;
+
+ /* wait_queue for waking the unifi_thread kernel thread */
+ wait_queue_head_t wakeup_q;
+ unsigned int wakeup_flag;
+
+ /*
+ * Use it to block the I/O thread when
+ * an error occurs or UniFi is reinitialised.
+ */
+ int block_thread;
+
+ char name[16];
+
+};
+
+
+struct unifi_priv {
+
+ card_t *card;
+ void *sdio;
+
+ /* Index into Unifi_instances[] for this device. */
+ int instance;
+ /* Reference count for this instance */
+ int ref_count;
+
+ /* Firmware images */
+ struct dlpriv fw_loader;
+ struct dlpriv fw_sta;
+
+ /* Char device related structures */
+ struct cdev unifi_cdev;
+ struct cdev unifiudi_cdev;
+ struct device *unifi_device;
+
+ /* Which wireless interface to use (1 - 2.4GHz, 2 - 5GHz) */
+ CSR_IFINTERFACE if_index;
+
+ struct net_device *netdev;
+
+ /* Name of node under /proc */
+ char proc_entry_name[64];
+
+ /* Back pointer to associated net device. */
+ struct net_device_stats stats;
+
+ /*
+ * Flag to reflect state of CONNECTED indication signal.
+ * This indicates whether we are "joined" an Access Point (i.e. have
+ * nominated an AP and are receiving beacons) but give no indication
+ * of whether we are authenticated and/or associated.
+ */
+ enum {
+ UnifiConnectedUnknown = -1,
+ UnifiNotConnected = 0,
+ UnifiConnected = 1,
+ } connected;
+
+ /*
+ * Flags:
+ * drop_unencrypted
+ * - Not used?
+ * netdev_registered
+ * - whether the netdev has been registered.
+ */
+ unsigned int drop_unencrypted : 1;
+ unsigned int netdev_registered : 1;
+
+ /* Our list of unifi linux clients. */
+ ul_client_t ul_clients[MAX_UDI_CLIENTS];
+
+ /* Mutex to protect using the logging hook after UDI client is gone */
+ struct semaphore udi_logging_mutex;
+ /* Pointer to the ul_clients[] array */
+ ul_client_t *logging_client;
+
+ /* A ul_client_t* used to send the netdev related MIB requests. */
+ ul_client_t *netdev_client;
+
+ /* The SME ul_client_t pointer. */
+ ul_client_t *sme_cli;
+
+ /* The AMP ul_client_t pointer. */
+ ul_client_t *amp_client;
+
+ /*
+ * Semaphore for locking the top-half to one user process.
+ * This is necessary to prevent multiple processes calling driver
+ * operations. This can happen because the network driver entry points
+ * can be called from multiple processes.
+ */
+#ifdef USE_DRIVER_LOCK
+ struct semaphore lock;
+#endif /* USE_DRIVER_LOCK */
+
+ /* Flag to say that an operation was aborted */
+ int io_aborted;
+
+ struct uf_thread bh_thread;
+
+#define UNIFI_INIT_NONE 0x00
+#define UNIFI_INIT_IN_PROGRESS 0x01
+#define UNIFI_INIT_FW_DOWNLOADED 0x02
+#define UNIFI_INIT_COMPLETED 0x04
+ unsigned char init_progress;
+
+ int sme_is_present;
+
+ /* The WMM features that UniFi uses in the current BSS */
+ unsigned int sta_wmm_capabilities;
+
+ /* Debug only */
+ char last_debug_string[256];
+ unsigned short last_debug_word16[16];
+
+#define UNIFI_MAX_MULTICAST_ADDRESSES 10
+ /* The multicast addresses list that the thread needs to set. */
+ u8 mc_list[UNIFI_MAX_MULTICAST_ADDRESSES*ETH_ALEN];
+ /* The multicast addresses count that the thread needs to set. */
+ int mc_list_count;
+
+#ifdef CSR_NATIVE_LINUX
+ /* wireless config */
+ struct wext_config wext_conf;
+
+ /* Mutex to protect the MLME blocking requests */
+ struct semaphore mlme_blocking_mutex;
+
+ /* The ul_client that provides the blocking API for WEXT calls */
+ ul_client_t *wext_client;
+
+ /* The ul_client that provides the blocking API for multicast workqueue */
+ ul_client_t *multicast_client;
+
+ /*
+ * Multicast list is set using a thread since we can not sleep
+ * in the netdev callback. The mc_list_count_stored keeps the
+ * number of the addresses already stored in the MIB.
+ */
+ int mc_list_count_stored;
+#endif /* CSR_NATIVE_LINUX */
+
+
+#ifdef CSR_SUPPORT_SME
+ wait_queue_head_t sme_request_wq;
+ /* Semaphore to protect the SME blocking requests */
+ struct semaphore sme_sem;
+ /* Structure to hold the SME blocking requests data*/
+ sme_reply_t sme_reply;
+
+ /* controlled port configuration */
+ controlled_port_config controlled_port_cfg;
+
+ /* Structure to hold a traffic protocol indication */
+ struct ta_ind {
+ struct work_struct task;
+ unifi_traffic_packettype packet_type;
+ unifi_protocol_direction direction;
+ unifi_MACAddress src_addr;
+ int in_use;
+ } ta_ind_work;
+
+ struct ta_sample_ind {
+ struct work_struct task;
+ unifi_traffic_stats stats;
+ int in_use;
+ } ta_sample_ind_work;
+
+ uint32 sta_ip_address;
+
+ /*
+ * Flag to reflect state of unifi_sys_wifi_on_*() progress.
+ * This indicates whether we are in an "wifi on" state when we are
+ * allowed to indication errors with unifi_mgt_wifi_off_ind()
+ */
+ enum {
+ wifi_on_unspecified = -1,
+ wifi_on_in_progress = 0,
+ wifi_on_done = 1,
+ } wifi_on_state;
+
+#ifdef CSR_SUPPORT_WEXT
+ /* The structure that holds all the connection configuration. */
+ unifi_ConnectionConfig connection_config;
+ int ignore_bssid_join;
+ struct iw_statistics wext_wireless_stats;
+ uint8 cached_tx_rate;
+
+ /* The MIB and MAC address files contents, read from userspace */
+ unifi_DataBlock mib_data;
+ unifi_MACAddress sta_mac_address;
+
+ int wep_tx_key_index;
+ wep_key_t wep_keys[NUM_WEPKEYS];
+
+ /* UNIFI_CFG related parameters */
+ uf_cfg_bcast_packet_filter_t packet_filters;
+ unsigned char *filter_tclas_ies;
+
+ struct work_struct sme_config_task;
+
+#endif /* CSR_SUPPORT_WEXT */
+
+#endif /* CSR_SUPPORT_SME */
+
+
+#ifdef CSR_SME_EMB
+ FsmContext* smepriv;
+
+ struct uf_thread sme_thread;
+
+#endif /* CSR_SME_EMB */
+
+
+#ifdef CSR_SME_USERSPACE
+ void *smepriv;
+
+#endif /* CSR_SME_USERSPACE */
+
+ card_info_t card_info;
+
+ /* Mutex to protect unifi_send_signal() */
+ spinlock_t send_signal_lock;
+
+
+ /*
+ * The workqueue to offload the TA run
+ * and the multicast addresses list set
+ */
+ struct workqueue_struct *unifi_workqueue;
+ struct work_struct multicast_list_task;
+
+ unsigned char *mib_cfm_buffer;
+ unsigned int mib_cfm_buffer_length;
+};
+
+
+#ifdef USE_DRIVER_LOCK
+#define LOCK_DRIVER(_p) down_interruptible(&(_p)->lock)
+#define UNLOCK_DRIVER(_p) up(&(_p)->lock)
+#else
+#define LOCK_DRIVER(_p) (void)(_p); /* as nothing */
+#define UNLOCK_DRIVER(_p) (void)(_p); /* as nothing */
+#endif /* USE_DRIVER_LOCK */
+
+
+/*
+ * SDIO related functions and callbacks
+ */
+int uf_sdio_load(void);
+void uf_sdio_unload(void);
+unifi_priv_t *register_unifi_sdio(void *sdio_dev, int bus_id, struct device *dev);
+void unregister_unifi_sdio(int bus_id);
+unifi_priv_t *unifi_find_instance(int inst);
+int unifi_find_priv(unifi_priv_t *priv);
+unifi_priv_t *unifi_get_instance(int inst);
+void unifi_put_instance(int inst);
+void uf_sdio_claim(void *sdio);
+void uf_sdio_release(void *sdio);
+
+/*
+ * Functions to allocate and free an ethernet device.
+ */
+unifi_priv_t *unifi_alloc_netdevice(void *sdio_dev, int bus_id);
+int unifi_free_netdevice(unifi_priv_t *priv);
+
+/*
+ * Firmware download related functions.
+ */
+int uf_run_unifihelper(unifi_priv_t *priv);
+int uf_request_firmware_files(unifi_priv_t *priv);
+
+
+/*
+ * Functions to create and delete the device nodes.
+ */
+int uf_create_device_nodes(unifi_priv_t *priv, int bus_id);
+void uf_destroy_device_nodes(unifi_priv_t *priv);
+
+/*
+ * Upper Edge Initialisation functions
+ */
+int uf_init_bh(unifi_priv_t *priv);
+int uf_init_hw(unifi_priv_t *priv);
+
+/* Thread related helper functions */
+int uf_start_thread(unifi_priv_t *priv, struct uf_thread *thread, int (*func)(void *));
+void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread);
+void uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread);
+
+
+/*
+ * Unifi Linux functions
+ */
+void ul_init_clients(unifi_priv_t *priv);
+
+/* Configuration flags */
+#define CLI_USING_WIRE_FORMAT 0x0002
+#define CLI_SME_USERSPACE 0x0020
+ul_client_t *ul_register_client(unifi_priv_t *priv,
+ unsigned int configuration,
+ udi_event_t udi_event_clbk);
+int ul_deregister_client(ul_client_t *pcli);
+
+int ul_send_signal_unpacked(unifi_priv_t *priv,
+ const CSR_SIGNAL *sigptr,
+ const bulk_data_param_t *bulkdata);
+int ul_send_signal_raw(unifi_priv_t *priv,
+ const unsigned char *sigptr, int siglen,
+ const bulk_data_param_t *bulkdata);
+
+void ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len);
+
+
+/*
+ * Data plane operations
+ */
+/*
+ * data_tx.c
+ */
+int unifi_ma_unitdata(unifi_priv_t *priv, ul_client_t *pcli,
+ CSR_SIGNAL *sig, const bulk_data_param_t *bulkdata);
+
+int unifi_mlme_eapol(unifi_priv_t *priv, ul_client_t *pcli,
+ CSR_SIGNAL *sig, const bulk_data_param_t *bulkdata);
+/*
+ * indications.c
+ */
+void unifi_ma_unitdata_status_ind(unifi_priv_t *priv,
+ const CSR_MA_UNITDATA_CONFIRM *ind);
+
+
+/*
+ * netdev.c
+ */
+const char *result_code_str(int result);
+
+int uf_install_qdisc(struct net_device *dev);
+void uf_resume_xmit(unifi_priv_t *priv);
+
+int uf_register_netdev(unifi_priv_t *priv);
+
+
+/*
+ * inet.c
+ */
+void unifi_register_inet_notifier(void);
+void unifi_unregister_inet_notifier(void);
+
+
+/*
+ * Suspend / Resume handlers
+ */
+void unifi_resume(void *ospriv);
+void unifi_suspend(void *ospriv);
+
+
+#define QOS_CAPABILITY_WMM_ENABLED 0x0001
+#define QOS_CAPABILITY_WMM_UAPSD 0x0002
+#define QOS_CAPABILITY_ACM_BE_ENABLED 0x0010
+#define QOS_CAPABILITY_ACM_BK_ENABLED 0x0020
+#define QOS_CAPABILITY_ACM_VI_ENABLED 0x0040
+#define QOS_CAPABILITY_ACM_VO_ENABLED 0x0080
+#define QOS_CAPABILITY_TS_BE_ENABLED 0x0100
+#define QOS_CAPABILITY_TS_BK_ENABLED 0x0200
+#define QOS_CAPABILITY_TS_VI_ENABLED 0x0400
+#define QOS_CAPABILITY_TS_VO_ENABLED 0x0800
+
+#ifdef INSTRUMENT_STARTUP
+#define TIME_MARK(str) printk(str ": %ldms\n", jiffies * 1000 / HZ)
+#else
+#define TIME_MARK(str) /* as nothing */
+#endif /* INSTRUMENT_STARTUP */
+
+
+/*
+ * unifi_dbg.c
+ */
+void debug_string_indication(unifi_priv_t *priv,
+ const unsigned char *extra,
+ unsigned int extralen);
+void debug_word16_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr);
+void debug_generic_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr);
+
+
+/*
+ * putest.c
+ */
+int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg);
+int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg);
+int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg);
+int unifi_putest_cmd52_read(unifi_priv_t *priv, unsigned char *arg);
+int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg);
+int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg);
+
+
+#endif /* __LINUX_UNIFI_PRIV_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.c
new file mode 100644
index 0000000..9abd6f4
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.c
@@ -0,0 +1,771 @@
+/*
+ * ***************************************************************************
+ * FILE: unifi_sme.c
+ *
+ * PURPOSE: SME related functions.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include "unifi_priv.h"
+
+
+
+int
+convert_sme_error(enum unifi_Status error)
+{
+ switch (error) {
+ case unifi_Success:
+ return 0;
+ case unifi_Error:
+ case unifi_NotFound:
+ case unifi_TimedOut:
+ case unifi_Cancelled:
+ case unifi_Unavailable:
+ return -EIO;
+ case unifi_NoRoom:
+ return -EBUSY;
+ case unifi_InvalidParameter:
+ return -EINVAL;
+ case unifi_Unsupported:
+ return -EOPNOTSUPP;
+ default:
+ return -EIO;
+ }
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * sme_log_event
+ *
+ * Callback function to be registered as the SME event callback.
+ * Copies the signal content into a new udi_log_t struct and adds
+ * it to the read queue for the SME client.
+ *
+ * Arguments:
+ * arg This is the value given to unifi_add_udi_hook, in
+ * this case a pointer to the client instance.
+ * signal Pointer to the received signal.
+ * signal_len Size of the signal structure in bytes.
+ * bulkdata Pointers to any associated bulk data.
+ * dir Direction of the signal. Zero means from host,
+ * non-zero means to host.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+sme_log_event(ul_client_t *pcli,
+ u8 *signal, int signal_len,
+ const bulk_data_param_t *bulkdata,
+ int dir)
+{
+ unifi_priv_t *priv;
+ CSR_SIGNAL *sigptr = (CSR_SIGNAL*) signal;
+ unifi_DataBlock mlmeCommand;
+ unifi_DataBlock dataref1;
+ unifi_DataBlock dataref2;
+
+ func_enter();
+
+ /* Just a sanity check */
+ if ((signal == NULL) || (signal_len <= 0)) {
+ return;
+ }
+
+ priv = unifi_find_instance(pcli->instance);
+ if (!priv) {
+ unifi_error(priv, "sme_emb_log_event: invalid priv\n");
+ return;
+ }
+
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "sme_emb_log_event: invalid smepriv\n");
+ return;
+ }
+
+ unifi_trace(priv, UDBG3,
+ "sme_emb - Process signal 0x%X %s\n",
+ *((uint16*)signal),
+ lookup_signal_name(*((uint16*)signal)));
+
+ /*
+ * We will silently discard a few signals that the SME does not to process.
+ * Discard ma-unidata-status.ind
+ */
+ if (sigptr->SignalPrimitiveHeader.SignalId == CSR_MA_UNITDATA_CONFIRM_ID) {
+ return;
+ }
+
+ mlmeCommand.length = signal_len;
+ mlmeCommand.data = (uint8*)signal;
+
+ dataref1.length = bulkdata->d[0].data_length;
+ if (dataref1.length > 0) {
+ dataref1.data = (uint8 *) bulkdata->d[0].os_data_ptr;
+ } else
+ {
+ dataref1.data = NULL;
+ }
+
+ dataref2.length = bulkdata->d[1].data_length;
+ if (dataref2.length > 0) {
+ dataref2.data = (uint8 *) bulkdata->d[1].os_data_ptr;
+ } else
+ {
+ dataref2.data = NULL;
+ }
+
+ unifi_sys_hip_ind(priv->smepriv, &mlmeCommand, &dataref1, &dataref2);
+
+ func_exit();
+} /* sme_log_event() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sme_controlled_port_state
+ *
+ * Return the state of the controlled port.
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * address Pointer to the destination for tx or sender for rx address
+ *
+ * Returns:
+ * An unifi_ControlledPortAction value.
+ * ---------------------------------------------------------------------------
+ */
+unifi_PortAction
+uf_sme_controlled_port_state(unifi_priv_t *priv, unsigned char *address)
+{
+ int i;
+
+ /* If the port configuration structure is empty, return Open. */
+ if (!priv->controlled_port_cfg.entries_in_use) {
+ unifi_trace(priv, UDBG5, "No port configurations.\n");
+ return unifi_8021x_PortOpen;
+ }
+ /* If the port configuration is common for all destinations, return it. */
+ if (priv->controlled_port_cfg.overide_action == CONTROLLED_PORT_OVERIDE) {
+ unifi_trace(priv, UDBG5, "Single port configuration (%d).\n",
+ priv->controlled_port_cfg.port_cfg[0].port_action);
+ return priv->controlled_port_cfg.port_cfg[0].port_action;
+ }
+
+ unifi_trace(priv, UDBG5, "Multiple port configurations.\n");
+ /* If multiple configurations exist.. */
+ for (i = 0; i < priv->controlled_port_cfg.entries_in_use; i++) {
+ /* .. go through the list and match the destination address. */
+ if (memcmp(address,
+ priv->controlled_port_cfg.port_cfg[i].mac_address,
+ ETH_ALEN) == 0) {
+ /* Return the desired action. */
+ return priv->controlled_port_cfg.port_cfg[i].port_action;
+ }
+ }
+
+ /* Could not find any information, return Open. */
+ unifi_trace(priv, UDBG5, "port configuration not found, return Open.\n");
+ return unifi_8021x_PortOpen;
+} /* uf_sme_controlled_port_state() */
+
+
+void
+uf_multicast_list_wq(struct work_struct *work)
+{
+ unifi_priv_t *priv = container_of(work, unifi_priv_t,
+ multicast_list_task);
+ int i;
+ unifi_MulticastAddressList multicast_address_list;
+ int mc_count;
+ u8 *mc_list;
+
+ unifi_trace(priv, UDBG5,
+ "uf_multicast_list_wq: list count = %d\n",
+ priv->mc_list_count);
+
+ mc_count = priv->mc_list_count;
+ mc_list = priv->mc_list;
+ /*
+ * Allocate a new list, need to free it later
+ * in unifi_mgt_multicast_address_cfm().
+ */
+ multicast_address_list.numElements = mc_count;
+ multicast_address_list.addresses = unifi_malloc(priv,
+ mc_count * sizeof(unifi_MACAddress));
+
+ /* Flush the current list */
+ unifi_sys_multicast_address_ind(priv->smepriv,
+ unifi_ListActionFlush,
+ &multicast_address_list);
+
+ if (multicast_address_list.addresses == NULL) {
+ return;
+ }
+
+ for (i = 0; i < mc_count; i++) {
+ memcpy(multicast_address_list.addresses[i].data,
+ mc_list, ETH_ALEN);
+ mc_list += ETH_ALEN;
+ }
+
+ if (priv->smepriv == NULL) {
+ unifi_free(priv, multicast_address_list.addresses);
+ return;
+ }
+
+ unifi_sys_multicast_address_ind(priv->smepriv,
+ unifi_ListActionAdd,
+ &multicast_address_list);
+
+ /* The SME will take a copy of the addreses*/
+ unifi_free(priv, multicast_address_list.addresses);
+}
+
+
+#ifdef CSR_SUPPORT_WEXT
+int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg)
+{
+ unifi_cfg_power_t cfg_power;
+ int rc;
+
+ if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ switch (cfg_power) {
+ case UNIFI_CFG_POWER_OFF:
+ rc = sme_sys_suspend(priv);
+ if (rc) {
+ return rc;
+ }
+ break;
+ case UNIFI_CFG_POWER_ON:
+ rc = sme_sys_resume(priv);
+ if (rc) {
+ return rc;
+ }
+ break;
+ default:
+ unifi_error(priv, "WIFI POWER: Unknown value.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg)
+{
+ unifi_cfg_powersave_t cfg_power_save;
+ unifi_AppValue sme_app_value;
+ int rc;
+
+ if (get_user(cfg_power_save, (unifi_cfg_powersave_t*)(((unifi_cfg_command_t*)arg) + 1))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ /* Get the coex info from the SME */
+ sme_app_value.id = unifi_PowerConfigValue;
+ rc = sme_mgt_get_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n");
+ return rc;
+ }
+
+ switch (cfg_power_save) {
+ case UNIFI_CFG_POWERSAVE_NONE:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveLow;
+ break;
+ case UNIFI_CFG_POWERSAVE_FAST:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveMed;
+ break;
+ case UNIFI_CFG_POWERSAVE_FULL:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveHigh;
+ break;
+ case UNIFI_CFG_POWERSAVE_AUTO:
+ sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveAuto;
+ break;
+ default:
+ unifi_error(priv, "POWERSAVE: Unknown value.\n");
+ return -EINVAL;
+ }
+
+ sme_app_value.id = unifi_PowerConfigValue;
+ rc = sme_mgt_set_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG: Set unifi_PowerConfigValue failed.\n");
+ }
+
+ return rc;
+}
+
+
+int unifi_cfg_power_supply(unifi_priv_t *priv, unsigned char *arg)
+{
+ unifi_cfg_powersupply_t cfg_power_supply;
+ unifi_AppValue sme_app_value;
+ int rc;
+
+ if (get_user(cfg_power_supply, (unifi_cfg_powersupply_t*)(((unifi_cfg_command_t*)arg) + 1))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ /* Get the coex info from the SME */
+ sme_app_value.id = unifi_HostConfigValue;
+ rc = sme_mgt_get_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n");
+ return rc;
+ }
+
+ switch (cfg_power_supply) {
+ case UNIFI_CFG_POWERSUPPLY_MAINS:
+ sme_app_value.unifi_Value_union.hostConfig.powerMode = unifi_HostActive;
+ break;
+ case UNIFI_CFG_POWERSUPPLY_BATTERIES:
+ sme_app_value.unifi_Value_union.hostConfig.powerMode = unifi_HostPowersave;
+ break;
+ default:
+ unifi_error(priv, "POWERSUPPLY: Unknown value.\n");
+ return -EINVAL;
+ }
+
+ sme_app_value.id = unifi_HostConfigValue;
+ rc = sme_mgt_set_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG: Set unifi_HostConfigValue failed.\n");
+ }
+
+ return rc;
+}
+
+
+int unifi_cfg_packet_filters(unifi_priv_t *priv, unsigned char *arg)
+{
+ unsigned char *tclas_buffer;
+ unsigned int tclas_buffer_length;
+ tclas_t *dhcp_tclas;
+ int rc;
+
+ /* Free any TCLASs previously allocated */
+ if (priv->packet_filters.tclas_ies_length) {
+ unifi_free(priv, priv->filter_tclas_ies);
+ priv->filter_tclas_ies = NULL;
+ }
+
+ tclas_buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int);
+ if (copy_from_user(&priv->packet_filters, (void*)tclas_buffer,
+ sizeof(uf_cfg_bcast_packet_filter_t))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the filter struct\n");
+ return -EFAULT;
+ }
+
+ tclas_buffer_length = priv->packet_filters.tclas_ies_length;
+
+ /* Allocate TCLASs if necessary */
+ if (priv->packet_filters.dhcp_filter) {
+ priv->packet_filters.tclas_ies_length += sizeof(tclas_t);
+ }
+ if (priv->packet_filters.tclas_ies_length > 0) {
+ priv->filter_tclas_ies = unifi_malloc(priv,
+ priv->packet_filters.tclas_ies_length);
+ if (priv->filter_tclas_ies == NULL) {
+ return -ENOMEM;
+ }
+ if (tclas_buffer_length) {
+ tclas_buffer += sizeof(uf_cfg_bcast_packet_filter_t) - sizeof(unsigned char*);
+ if (copy_from_user(priv->filter_tclas_ies,
+ tclas_buffer,
+ tclas_buffer_length)) {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the TCLAS buffer\n");
+ return -EFAULT;
+ }
+ }
+ }
+
+ if(priv->packet_filters.dhcp_filter)
+ {
+ /* Append the DHCP tclas IE */
+ dhcp_tclas = (tclas_t*)(priv->filter_tclas_ies + tclas_buffer_length);
+ memset(dhcp_tclas, 0, sizeof(tclas_t));
+ dhcp_tclas->element_id = 14;
+ dhcp_tclas->length = sizeof(tcpip_clsfr_t) + 1;
+ dhcp_tclas->user_priority = 0;
+ dhcp_tclas->tcp_ip_cls_fr.cls_fr_type = 1;
+ dhcp_tclas->tcp_ip_cls_fr.version = 4;
+ ((uint8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[0] = 0x00;
+ ((uint8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[1] = 0x44;
+ ((uint8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[0] = 0x00;
+ ((uint8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[1] = 0x43;
+ dhcp_tclas->tcp_ip_cls_fr.protocol = 0x11;
+ dhcp_tclas->tcp_ip_cls_fr.cls_fr_mask = 0x58; //bits: 3,4,6
+ }
+
+ rc = sme_mgt_packet_filter_set(priv);
+
+ return rc;
+}
+
+
+int unifi_cfg_wmm_qos_info(unifi_priv_t *priv, unsigned char *arg)
+{
+ uint8 wmm_qos_info;
+ int rc = 0;
+
+ if (get_user(wmm_qos_info, (uint8*)(((unifi_cfg_command_t*)arg) + 1))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ /* Store the value in the connection info */
+ priv->connection_config.wmmQosInfo = wmm_qos_info;
+
+ return rc;
+}
+
+
+int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg)
+{
+ uint32 addts_tid;
+ uint8 addts_ie_length;
+ uint8 *addts_ie;
+ uint8 *addts_params;
+ unifi_DataBlock tspec;
+ unifi_DataBlock tclas;
+ int rc;
+
+ addts_params = (uint8*)(((unifi_cfg_command_t*)arg) + 1);
+ if (get_user(addts_tid, (uint32*)addts_params)) {
+ unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ addts_params += sizeof(uint32);
+ if (get_user(addts_ie_length, (uint8*)addts_params)) {
+ unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG4, "addts: tid = 0x%x ie_length = %d\n",
+ addts_tid, addts_ie_length);
+
+ addts_ie = unifi_malloc(priv, addts_ie_length);
+ if (addts_ie == NULL) {
+ unifi_error(priv,
+ "unifi_cfg_wmm_addts: Failed to malloc %d bytes for addts_ie buffer\n",
+ addts_ie_length);
+ return -ENOMEM;
+ }
+
+ addts_params += sizeof(uint8);
+ rc = copy_from_user(addts_ie, addts_params, addts_ie_length);
+ if (rc) {
+ unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the addts buffer\n");
+ unifi_free(priv, addts_ie);
+ return -EFAULT;
+ }
+
+ tspec.data = addts_ie;
+ tspec.length = addts_ie_length;
+ tclas.data = NULL;
+ tclas.length = 0;
+
+ rc = sme_mgt_tspec(priv, unifi_ListActionAdd, addts_tid,
+ &tspec, &tclas);
+
+ unifi_free(priv, addts_ie);
+ return rc;
+}
+
+
+int unifi_cfg_wmm_delts(unifi_priv_t *priv, unsigned char *arg)
+{
+ uint32 delts_tid;
+ uint8 *delts_params;
+ unifi_DataBlock tspec;
+ unifi_DataBlock tclas;
+ int rc;
+
+ delts_params = (uint8*)(((unifi_cfg_command_t*)arg) + 1);
+ if (get_user(delts_tid, (uint32*)delts_params)) {
+ unifi_error(priv, "unifi_cfg_wmm_delts: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ unifi_trace(priv, UDBG4, "delts: tid = 0x%x\n", delts_tid);
+
+ tspec.data = tclas.data = NULL;
+ tspec.length = tclas.length = 0;
+
+ rc = sme_mgt_tspec(priv, unifi_ListActionRemove, delts_tid,
+ &tspec, &tclas);
+
+ return rc;
+}
+
+
+int unifi_cfg_get_info(unifi_priv_t *priv, unsigned char *arg)
+{
+ unifi_AppValue sme_app_value;
+ unifi_cfg_get_t get_cmd;
+ int rc;
+
+ if (get_user(get_cmd, (unifi_cfg_get_t*)(((unifi_cfg_command_t*)arg) + 1))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
+ return -EFAULT;
+ }
+
+ switch (get_cmd) {
+ case UNIFI_CFG_GET_COEX:
+ /* Get the coex info from the SME */
+ sme_app_value.id = unifi_CoexInfoValue;
+ rc = sme_mgt_get_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG: Get unifi_CoexInfoValue failed.\n");
+ return rc;
+ }
+
+ /* Copy the info to the out buffer */
+ if (copy_to_user((void*)arg,
+ &sme_app_value.unifi_Value_union.coexInfo,
+ sizeof(unifi_CoexInfo))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to copy the coex info\n");
+ return -EFAULT;
+ }
+ break;
+ case UNIFI_CFG_GET_POWER_MODE:
+ sme_app_value.id = unifi_PowerConfigValue;
+ rc = sme_mgt_get_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n");
+ return rc;
+ }
+
+ /* Copy the info to the out buffer */
+ if (copy_to_user((void*)arg,
+ &sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel,
+ sizeof(unifi_PowerSaveLevel))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to copy the power save info\n");
+ return -EFAULT;
+ }
+ break;
+ case UNIFI_CFG_GET_POWER_SUPPLY:
+ sme_app_value.id = unifi_HostConfigValue;
+ rc = sme_mgt_get_value(priv, &sme_app_value);
+ if (rc) {
+ unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n");
+ return rc;
+ }
+
+ /* Copy the info to the out buffer */
+ if (copy_to_user((void*)arg,
+ &sme_app_value.unifi_Value_union.hostConfig.powerMode,
+ sizeof(unifi_HostPowerMode))) {
+ unifi_error(priv, "UNIFI_CFG: Failed to copy the host power mode\n");
+ return -EFAULT;
+ }
+ break;
+ case UNIFI_CFG_GET_VERSIONS:
+ break;
+ default:
+ unifi_error(priv, "unifi_cfg_get_info: Unknown value.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+void
+uf_sme_config_wq(struct work_struct *work)
+{
+ unifi_priv_t *priv = container_of(work, unifi_priv_t, sme_config_task);
+ unifi_AppValue sme_app_value;
+
+ sme_app_value.id = unifi_SMEConfigValue;
+ if (sme_mgt_get_value(priv, &sme_app_value)) {
+ unifi_warning(priv, "uf_sme_config_wq: Get unifi_SMEConfigValue failed.\n");
+ return;
+ }
+
+ sme_app_value.unifi_Value_union.smeConfig.trustLevel = (unifi_80211dTrustLevel)tl_80211d;
+ if (sme_mgt_set_value(priv, &sme_app_value)) {
+ unifi_warning(priv, "uf_sme_config_wq: Set unifi_SMEConfigValue failed.\n");
+ return;
+ }
+
+} /* uf_sme_config_wq() */
+
+#endif /* CSR_SUPPORT_WEXT */
+
+
+/*
+ * This file also contains the implementation of the asyncronous
+ * requests to the SME.
+ *
+ * Before calling an asyncronous SME function, we call sme_init_request()
+ * which gets hold of the SME semaphore and updates the request status.
+ * The semaphore makes sure that there is only one pending request to
+ * the SME at a time.
+ *
+ * Now we are ready to call the SME function, but only if
+ * sme_init_request() has returned 0.
+ *
+ * When the SME function returns, we need to wait
+ * for the reply. This is done in sme_wait_for_reply().
+ * If the request times-out, the request status is set to SME_REQUEST_TIMEDOUT
+ * and the sme_wait_for_reply() returns.
+ *
+ * If the SME replies in time, we call sme_complete_request().
+ * There we change the request status to SME_REQUEST_RECEIVED. This will
+ * wake up the process waiting on sme_wait_for_reply().
+ * It is important that we copy the reply data in priv->sme_reply
+ * before calling sme_complete_request().
+ *
+ */
+
+
+int
+sme_init_request(unifi_priv_t *priv)
+{
+ if (priv == NULL) {
+ unifi_error(priv, "sme_init_request: Invalid priv\n");
+ return -EIO;
+ }
+
+ /* Grab the SME semaphore until the reply comes, or timeout */
+ if (down_interruptible(&priv->sme_sem)) {
+ unifi_error(priv, "sme_init_request: Failed to get SME semaphore\n");
+ return -EIO;
+ }
+ priv->sme_reply.request_status = SME_REQUEST_PENDING;
+
+ return 0;
+
+} /* sme_init_request() */
+
+
+void
+sme_complete_request(unifi_priv_t *priv, unifi_Status reply_status)
+{
+ if (priv == NULL) {
+ unifi_error(priv, "sme_complete_request: Invalid priv\n");
+ return;
+ }
+
+ if (priv->sme_reply.request_status != SME_REQUEST_PENDING) {
+ unifi_trace(priv, UDBG5,
+ "sme_complete_request: request not pending (s:%d)\n",
+ priv->sme_reply.request_status);
+ return;
+ }
+ priv->sme_reply.request_status = SME_REQUEST_RECEIVED;
+ priv->sme_reply.reply_status = reply_status;
+
+ wake_up_interruptible(&priv->sme_request_wq);
+
+ return;
+}
+
+
+int
+sme_wait_for_reply(unifi_priv_t *priv,
+ unsigned long timeout)
+{
+ long r;
+
+ unifi_trace(priv, UDBG5, "sme_wait_for_reply: sleep\n");
+ r = wait_event_interruptible_timeout(priv->sme_request_wq,
+ (priv->sme_reply.request_status != SME_REQUEST_PENDING),
+ msecs_to_jiffies(timeout));
+ unifi_trace(priv, UDBG5, "sme_wait_for_reply: awake\n");
+
+ if (r == -ERESTARTSYS) {
+ /* The thread was killed */
+ up(&priv->sme_sem);
+ return r;
+ }
+ if ((r == 0) && (priv->sme_reply.request_status != SME_REQUEST_RECEIVED)) {
+ unifi_notice(priv, "Timeout waiting for SME to reply.\n");
+
+#if (defined UNIFI_DEBUG) && (defined CSR_SME_EMB)
+ /* Get the SME to dump a full state dump */
+ if (priv->smepriv != NULL) {
+ fsm_debug_dump(priv->smepriv);
+ }
+#endif /* CSR_SME_EMB */
+
+ priv->sme_reply.request_status = SME_REQUEST_TIMEDOUT;
+
+ /* Release the SME semaphore that was downed in sme_init_request() */
+ up(&priv->sme_sem);
+
+ return -ETIMEDOUT;
+ }
+
+ /* Release the SME semaphore that was downed in sme_init_request() */
+ up(&priv->sme_sem);
+
+ return 0;
+} /* sme_wait_for_reply() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_ta_ind_wq
+ *
+ * Deferred work queue function to send Traffic Analysis protocols
+ * indications to the SME.
+ * These are done in a deferred work queue for two reasons:
+ * - the unifi_sys_.._ind() functions are not safe for atomic context
+ * - we want to load the main driver data path as lightly as possible
+ *
+ * The TA classifications already come from a workqueue.
+ *
+ * Arguments:
+ * work Pointer to work queue item.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void
+uf_ta_ind_wq(struct work_struct *work)
+{
+ struct ta_ind *ind = container_of(work, struct ta_ind, task);
+ unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_ind_work);
+
+
+ unifi_sys_traffic_protocol_ind(priv->smepriv,
+ ind->packet_type,
+ ind->direction,
+ &ind->src_addr);
+ ind->in_use = 0;
+
+} /* uf_ta_ind_wq() */
+
+void
+uf_ta_sample_ind_wq(struct work_struct *work)
+{
+ struct ta_sample_ind *ind = container_of(work, struct ta_sample_ind, task);
+ unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_sample_ind_work);
+
+
+ unifi_sys_traffic_sample_ind(priv->smepriv, &ind->stats);
+
+ ind->in_use = 0;
+
+} /* uf_ta_sample_ind_wq() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.h
new file mode 100644
index 0000000..878c208
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_sme.h
@@ -0,0 +1,179 @@
+/*
+ * ***************************************************************************
+ * FILE: unifi_sme.h
+ *
+ * PURPOSE: SME related definitions.
+ *
+ * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#ifndef __LINUX_UNIFI_SME_H__
+#define __LINUX_UNIFI_SME_H__ 1
+
+#include <linux/kernel.h>
+
+#ifdef CSR_SME_EMB
+#include "sme_csr_emb/sme_emb.h"
+#endif
+
+#ifdef CSR_SME_USERSPACE
+#include "sme_csr/sme_userspace.h"
+#endif
+
+/*
+ * The version of the driver's SME API.
+ */
+#define SME_API_MAJOR_VERSION 0
+#define SME_API_MINOR_VERSION 2
+
+
+typedef int unifi_controlled_port_action;
+
+typedef struct
+{
+ unifi_controlled_port_action port_action;
+ u8 mac_address[6];
+} unifi_controlled_port_cfg;
+
+#define UNIFI_MAX_CONNECTIONS 8
+#define CONTROLLED_PORT_NOT_OVERIDE 0
+#define CONTROLLED_PORT_OVERIDE 1
+
+typedef struct
+{
+ int entries_in_use;
+ int overide_action;
+ unifi_controlled_port_cfg port_cfg[UNIFI_MAX_CONNECTIONS];
+} controlled_port_config;
+
+
+enum sme_request_status {
+ SME_REQUEST_EMPTY,
+ SME_REQUEST_PENDING,
+ SME_REQUEST_RECEIVED,
+ SME_REQUEST_TIMEDOUT,
+};
+
+/* Structure to hold a UDI logged signal */
+typedef struct {
+
+ /* The current status of the request */
+ enum sme_request_status request_status;
+
+ /* The status the SME has passed to us */
+ unifi_Status reply_status;
+
+ /* The message the SME has passed to us */
+ unifi_AppValue reply_app_value;
+
+ /* The SME versions returned by MMI */
+ unifi_ScanResultList reply_scan_results;
+
+} sme_reply_t;
+
+
+int uf_sme_configure_controlled_port(unifi_priv_t *priv,
+ const unifi_controlled_port_cfg *port_cfg);
+unifi_PortAction uf_sme_controlled_port_state(unifi_priv_t *priv,
+ unsigned char *address);
+
+
+/* Callback for event logging to SME clients */
+void sme_log_event(ul_client_t *client, u8 *signal, int signal_len,
+ const bulk_data_param_t *bulkdata, int dir);
+
+/* The workqueue task to the set the multicast addresses list */
+void uf_multicast_list_wq(struct work_struct *work);
+
+/* The workqueue task to execute the TA module */
+void uf_ta_wq(struct work_struct *work);
+
+
+/*
+ * SME blocking helper functions
+ */
+
+#define UNIFI_SME_MGT_SHORT_TIMEOUT 3000
+#define UNIFI_SME_MGT_LONG_TIMEOUT 10000
+#define UNIFI_SME_SYS_LONG_TIMEOUT 1000
+int sme_init_request(unifi_priv_t *priv);
+
+int sme_wait_for_reply(unifi_priv_t *priv, unsigned long timeout);
+
+void sme_complete_request(unifi_priv_t *priv, unifi_Status reply_status);
+
+
+/*
+ * Blocking functions using the SME SYS API.
+ */
+int sme_sys_suspend(unifi_priv_t *priv);
+int sme_sys_resume(unifi_priv_t *priv);
+
+
+/*
+ * Traffic Analysis workqueue jobs
+ */
+void uf_ta_ind_wq(struct work_struct *work);
+void uf_ta_sample_ind_wq(struct work_struct *work);
+
+/*
+ * SME config workqueue job
+ */
+void uf_sme_config_wq(struct work_struct *work);
+
+
+#ifdef CSR_SUPPORT_WEXT
+/*
+ * Blocking functions using the SME MGT API.
+ */
+int sme_mgt_wifi_on(unifi_priv_t *priv);
+int sme_mgt_wifi_off(unifi_priv_t *priv);
+int sme_mgt_set_value_async(unifi_priv_t *priv, unifi_AppValue *app_value);
+int sme_mgt_get_value_async(unifi_priv_t *priv, unifi_AppValue *app_value);
+int sme_mgt_get_value(unifi_priv_t *priv, unifi_AppValue *app_value);
+int sme_mgt_set_value(unifi_priv_t *priv, unifi_AppValue *app_value);
+int sme_mgt_scan_full(unifi_priv_t *priv, unifi_SSID *specific_ssid);
+int sme_mgt_scan_results_get_async(unifi_priv_t *priv,
+ struct iw_request_info *info,
+ char *scan_results,
+ long scan_results_len);
+int sme_mgt_disconnect(unifi_priv_t *priv);
+int sme_mgt_connect(unifi_priv_t *priv);
+int sme_mgt_get_versions(unifi_priv_t *priv, unifi_Versions *versions);
+int sme_mgt_key(unifi_priv_t *priv, unifi_Key *sme_key,
+ enum unifi_ListAction action);
+int sme_mgt_pmkid(unifi_priv_t *priv, unifi_ListAction action,
+ unifi_PmkidList *pmkid_list);
+int sme_mgt_packet_filter_set(unifi_priv_t *priv);
+int sme_mgt_mib_get(unifi_priv_t *priv,
+ unsigned char *varbind, int *length);
+int sme_mgt_mib_set(unifi_priv_t *priv,
+ unsigned char *varbind, int length);
+int sme_mgt_tspec(unifi_priv_t *priv, unifi_ListAction action,
+ uint32 tid, unifi_DataBlock *tspec, unifi_DataBlock *tclas);
+
+int unifi_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ char *current_ev, char *end_buf,
+ unifi_ScanResult *scan_data,
+ int scan_index);
+
+int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg);
+int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg);
+int unifi_cfg_power_supply(unifi_priv_t *priv, unsigned char *arg);
+int unifi_cfg_packet_filters(unifi_priv_t *priv, unsigned char *arg);
+int unifi_cfg_wmm_qos_info(unifi_priv_t *priv, unsigned char *arg);
+int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg);
+int unifi_cfg_wmm_delts(unifi_priv_t *priv, unsigned char *arg);
+int unifi_cfg_get_info(unifi_priv_t *priv, unsigned char *arg);
+
+#endif /* CSR_SUPPORT_WEXT */
+
+int convert_sme_error(enum unifi_Status error);
+
+
+#endif /* __LINUX_UNIFI_SME_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_wext.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_wext.h
new file mode 100644
index 0000000..08f8ce8
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifi_wext.h
@@ -0,0 +1,120 @@
+/*
+ *****************************************************************************
+ *
+ * FILE : unifi_wext.h
+ *
+ * PURPOSE : Private header file for unifi driver support to wireless extensions.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+*****************************************************************************
+ */
+#ifndef __LINUX_UNIFI_WEXT_H__
+#define __LINUX_UNIFI_WEXT_H__ 1
+
+#include <linux/kernel.h>
+#include <net/iw_handler.h>
+
+/*
+ * wext.c
+ */
+/* A few details needed for WEP (Wireless Equivalent Privacy) */
+#define UNIFI_MAX_KEY_SIZE 16
+#define NUM_WEPKEYS 4
+#define SMALL_KEY_SIZE 5
+#define LARGE_KEY_SIZE 13
+typedef struct wep_key_t {
+ int len;
+ unsigned char key[UNIFI_MAX_KEY_SIZE]; /* 40-bit and 104-bit keys */
+} wep_key_t;
+
+#define UNIFI_SCAN_ACTIVE 0
+#define UNIFI_SCAN_PASSIVE 1
+#define UNIFI_MAX_SSID_LEN 32
+
+#define MAX_WPA_IE_LEN 64
+#define MAX_RSN_IE_LEN 255
+
+/*
+ * Function to register in the netdev to report wireless stats.
+ */
+struct iw_statistics *unifi_get_wireless_stats(struct net_device *dev);
+
+void uf_sme_wext_set_defaults(unifi_priv_t *priv);
+
+
+/*
+ * wext_events.c
+ */
+/* Functions to generate Wireless Extension events */
+void wext_send_scan_results_event(unifi_priv_t *priv);
+void wext_send_assoc_event(unifi_priv_t *priv, unsigned char *bssid,
+ unsigned char *req_ie, int req_ie_len,
+ unsigned char *resp_ie, int resp_ie_len,
+ unsigned char *scan_ie, unsigned int scan_ie_len);
+void wext_send_disassoc_event(unifi_priv_t *priv);
+void wext_send_michaelmicfailure_event(unifi_priv_t *priv,
+ const CSR_MLME_MICHAELMICFAILURE_INDICATION *ind);
+
+
+static inline int
+uf_iwe_stream_add_point(struct iw_request_info *info, char *start, char *stop,
+ struct iw_event *piwe, char *extra)
+{
+ char *new_start;
+
+ new_start = iwe_stream_add_point(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined (IW_REQUEST_FLAG_COMPAT)
+ info,
+#endif
+ start, stop, piwe, extra);
+ if (unlikely(new_start == start))
+ {
+ return -E2BIG;
+ }
+
+ return (new_start - start);
+}
+
+
+static inline int
+uf_iwe_stream_add_event(struct iw_request_info *info, char *start, char *stop,
+ struct iw_event *piwe, int len)
+{
+ char *new_start;
+
+ new_start = iwe_stream_add_event(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined(IW_REQUEST_FLAG_COMPAT)
+ info,
+#endif
+ start, stop, piwe, len);
+ if (unlikely(new_start == start)) {
+ return -E2BIG;
+ }
+
+ return (new_start - start);
+}
+
+static inline int
+uf_iwe_stream_add_value(struct iw_request_info *info, char *stream, char *start,
+ char *stop, struct iw_event *piwe, int len)
+{
+ char *new_start;
+
+ new_start = iwe_stream_add_value(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) || defined(IW_REQUEST_FLAG_COMPAT)
+ info,
+#endif
+ stream, start, stop, piwe, len);
+ if (unlikely(new_start == start)) {
+ return -E2BIG;
+ }
+
+ return (new_start - start);
+}
+
+
+#endif /* __LINUX_UNIFI_WEXT_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifiio.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifiio.h
new file mode 100644
index 0000000..95d9ced
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/unifiio.h
@@ -0,0 +1,292 @@
+/*
+ * ---------------------------------------------------------------------------
+ *
+ * FILE: unifiio.h
+ *
+ * Public definitions for the UniFi linux driver.
+ * This is mostly ioctl command values and structs.
+ *
+ * Include <sys/ioctl.h> or similar before this file
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#ifndef __UNIFIIO_H__
+#define __UNIFIIO_H__
+
+#include <linux/types.h>
+
+#define UNIFI_GET_UDI_ENABLE _IOR('u', 1, int)
+#define UNIFI_SET_UDI_ENABLE _IOW('u', 2, int)
+/* Values for UDI_ENABLE */
+#define UDI_ENABLE_DATA 0x1
+#define UDI_ENABLE_CONTROL 0x2
+
+/* MIB set/get. Arg is a pointer to a varbind */
+#define UNIFI_GET_MIB _IOWR('u', 3, unsigned char *)
+#define UNIFI_SET_MIB _IOW ('u', 4, unsigned char *)
+#define MAX_VARBIND_LENGTH 127
+
+/* Private configuration commands */
+#define UNIFI_CFG _IOWR('u', 5, unsigned char *)
+/*
+ * <------------------ Read/Write Buffer -------------------->
+ * _____________________________________________________________
+ * | Cmd | Arg | ... Buffer (opt) ... |
+ * -------------------------------------------------------------
+ * <-- uint --><-- uint --><----- unsigned char buffer ------>
+ *
+ * Cmd: A unifi_cfg_command_t command.
+ * Arg: Out:Length if Cmd==UNIFI_CFG_GET
+ * In:PowerOnOff if Cmd==UNIFI_CFG_POWER
+ * In:PowerMode if Cmd==UNIFI_CFG_POWERSAVE
+ * In:Length if Cmd==UNIFI_CFG_FILTER
+ * In:WMM Qos Info if Cmd==UNIFI_CFG_WMM_QOS_INFO
+ * Buffer: Out:Data if Cmd==UNIFI_CFG_GET
+ * NULL if Cmd==UNIFI_CFG_POWER
+ * NULL if Cmd==UNIFI_CFG_POWERSAVE
+ * In:Filters if Cmd==UNIFI_CFG_FILTER
+ *
+ * where Filters is a uf_cfg_bcast_packet_filter_t structure
+ * followed by 0 - n tclas_t structures. The length of the tclas_t
+ * structures is obtained by uf_cfg_bcast_packet_filter_t::tclas_ies_length.
+ */
+
+
+#define UNIFI_PUTEST _IOWR('u', 6, unsigned char *)
+/*
+ * <------------------ Read/Write Buffer -------------------->
+ * _____________________________________________________________
+ * | Cmd | Arg | ... Buffer (opt) ... |
+ * -------------------------------------------------------------
+ * <-- uint --><-- uint --><----- unsigned char buffer ------>
+ *
+ * Cmd: A unifi_putest_command_t command.
+ * Arg: N/A if Cmd==UNIFI_PUTEST_START
+ * N/A if Cmd==UNIFI_PUTEST_STOP
+ * In:int (Clock Speed) if Cmd==UNIFI_PUTEST_SET_SDIO_CLOCK
+ * In/Out:sizeof(unifi_putest_cmd52) if Cmd==UNIFI_PUTEST_CMD52_READ
+ * In:sizeof(unifi_putest_cmd52) if Cmd==UNIFI_PUTEST_CMD52_WRITE
+ * In:uint (f/w file name length) if Cmd==UNIFI_PUTEST_DL_FW
+ * Buffer: NULL if Cmd==UNIFI_PUTEST_START
+ * NULL if Cmd==UNIFI_PUTEST_STOP
+ * NULL if Cmd==UNIFI_PUTEST_SET_SDIO_CLOCK
+ * In/Out:unifi_putest_cmd52 if Cmd==UNIFI_PUTEST_CMD52_READ
+ * In:unifi_putest_cmd52 if Cmd==UNIFI_PUTEST_CMD52_WRITE
+ * In:f/w file name if Cmd==UNIFI_PUTEST_DL_FW
+ */
+
+
+/* debugging */
+#define UNIFI_KICK _IO ('u', 0x10)
+#define UNIFI_SET_DEBUG _IO ('u', 0x11)
+#define UNIFI_SET_TRACE _IO ('u', 0x12)
+
+#define UNIFI_GET_INIT_STATUS _IOR ('u', 0x15, int)
+#define UNIFI_SET_UDI_LOG_MASK _IOR('u', 0x18, unifiio_filter_t)
+#define UNIFI_SET_UDI_SNAP_MASK _IOW('u', 0x1a, unifiio_snap_filter_t)
+#define UNIFI_SET_AMP_ENABLE _IOWR('u', 0x1b, int)
+
+#define UNIFI_INIT_HW _IOR ('u', 0x13, unsigned char)
+#define UNIFI_INIT_NETDEV _IOW ('u', 0x14, unsigned char[6])
+#define UNIFI_SME_PRESENT _IOW ('u', 0x19, int)
+
+#define UNIFI_CFG_PERIOD_TRAFFIC _IOW ('u', 0x21, unsigned char *)
+#define UNIFI_CFG_UAPSD_TRAFFIC _IOW ('u', 0x22, unsigned char)
+
+/*
+ * Following reset, f/w may only be downloaded using CMD52.
+ * This is slow, so there is a facility to download a secondary
+ * loader first which supports CMD53.
+ * If loader_len is > 0, then loader_data is assumed to point to
+ * a suitable secondary loader that can be used to download the
+ * main image.
+ *
+ * The driver will run the host protocol initialisation sequence
+ * after downloading the image.
+ *
+ * If both lengths are zero, then the f/w is assumed to have been
+ * booted from Flash and the host protocol initialisation sequence
+ * is run.
+ */
+typedef struct {
+
+ /* Number of bytes in the image */
+ int img_len;
+
+ /* Pointer to image data. */
+ unsigned char *img_data;
+
+
+ /* Number of bytes in the loader image */
+ int loader_len;
+
+ /* Pointer to loader image data. */
+ unsigned char *loader_data;
+
+} unifiio_img_t;
+
+
+/* Structure of data read from the unifi device. */
+typedef struct
+{
+ /* Length (in bytes) of entire structure including appended bulk data */
+ int length;
+
+ /* System time (in milliseconds) that signal was transferred */
+ int timestamp;
+
+ /* Direction in which signal was transferred. */
+ int direction;
+#define UDI_FROM_HOST 0
+#define UDI_TO_HOST 1
+#define UDI_CONFIG_IND 2
+
+ /* The length of the signal (in bytes) not including bulk data */
+ int signal_length;
+
+ /* Signal body follows, then any bulk data */
+
+} udi_msg_t;
+
+
+typedef enum
+{
+ UfSigFil_AllOn = 0, /* Log all signal IDs */
+ UfSigFil_AllOff = 1, /* Don't log any signal IDs */
+ UfSigFil_SelectOn = 2, /* Log these signal IDs */
+ UfSigFil_SelectOff = 3 /* Don't log these signal IDs */
+} uf_sigfilter_action_t;
+
+typedef struct {
+
+ /* Number of 16-bit ints in the sig_ids array */
+ int num_sig_ids;
+ /* The action to perform */
+ uf_sigfilter_action_t action;
+ /* List of signal IDs to pass or block */
+ unsigned short *sig_ids;
+
+} unifiio_filter_t;
+
+
+typedef struct {
+ /* Number of 16-bit ints in the protocols array */
+ uint16 count;
+ /* List of protocol ids to pass */
+ uint16 *protocols;
+} unifiio_snap_filter_t;
+
+
+
+typedef enum unifi_putest_command {
+ UNIFI_PUTEST_START,
+ UNIFI_PUTEST_STOP,
+ UNIFI_PUTEST_SET_SDIO_CLOCK,
+ UNIFI_PUTEST_CMD52_READ,
+ UNIFI_PUTEST_CMD52_WRITE,
+ UNIFI_PUTEST_DL_FW
+} unifi_putest_command_t;
+
+
+struct unifi_putest_cmd52 {
+ int funcnum;
+ unsigned long addr;
+ unsigned char data;
+};
+
+
+
+
+
+
+typedef enum unifi_cfg_command {
+ UNIFI_CFG_GET,
+ UNIFI_CFG_POWER,
+ UNIFI_CFG_POWERSAVE,
+ UNIFI_CFG_FILTER,
+ UNIFI_CFG_POWERSUPPLY,
+ UNIFI_CFG_WMM_QOSINFO,
+ UNIFI_CFG_WMM_ADDTS,
+ UNIFI_CFG_WMM_DELTS
+} unifi_cfg_command_t;
+
+typedef enum unifi_cfg_power {
+ UNIFI_CFG_POWER_UNSPECIFIED,
+ UNIFI_CFG_POWER_OFF,
+ UNIFI_CFG_POWER_ON
+} unifi_cfg_power_t;
+
+typedef enum unifi_cfg_powersupply {
+ UNIFI_CFG_POWERSUPPLY_UNSPECIFIED,
+ UNIFI_CFG_POWERSUPPLY_MAINS,
+ UNIFI_CFG_POWERSUPPLY_BATTERIES
+} unifi_cfg_powersupply_t;
+
+typedef enum unifi_cfg_powersave {
+ UNIFI_CFG_POWERSAVE_UNSPECIFIED,
+ UNIFI_CFG_POWERSAVE_NONE,
+ UNIFI_CFG_POWERSAVE_FAST,
+ UNIFI_CFG_POWERSAVE_FULL,
+ UNIFI_CFG_POWERSAVE_AUTO
+} unifi_cfg_powersave_t;
+
+typedef enum unifi_cfg_get {
+ UNIFI_CFG_GET_COEX,
+ UNIFI_CFG_GET_POWER_MODE,
+ UNIFI_CFG_GET_VERSIONS,
+ UNIFI_CFG_GET_POWER_SUPPLY
+} unifi_cfg_get_t;
+
+#define UNIFI_CFG_FILTER_NONE 0x0000
+#define UNIFI_CFG_FILTER_DHCP 0x0001
+#define UNIFI_CFG_FILTER_ARP 0x0002
+#define UNIFI_CFG_FILTER_NBNS 0x0004
+#define UNIFI_CFG_FILTER_NBDS 0x0008
+#define UNIFI_CFG_FILTER_CUPS 0x0010
+#define UNIFI_CFG_FILTER_ALL 0xFFFF
+
+
+typedef struct uf_cfg_bcast_packet_filter
+{
+ unsigned long filter_mode; //as defined by HIP protocol
+ unsigned char arp_filter;
+ unsigned char dhcp_filter;
+ unsigned long tclas_ies_length; // length of tclas_ies in bytes
+ unsigned char tclas_ies[1]; // variable length depending on above field
+} uf_cfg_bcast_packet_filter_t;
+
+
+
+typedef struct tcpic_clsfr
+{
+ __u8 cls_fr_type;
+ __u8 cls_fr_mask;
+ __u8 version;
+ __u8 source_ip_addr[4];
+ __u8 dest_ip_addr[4];
+ __u16 source_port;
+ __u16 dest_port;
+ __u8 dscp;
+ __u8 protocol;
+ __u8 reserved;
+} __attribute__ ((packed)) tcpip_clsfr_t;
+
+typedef struct tclas {
+ __u8 element_id;
+ __u8 length;
+ __u8 user_priority;
+ tcpip_clsfr_t tcp_ip_cls_fr;
+} __attribute__ ((packed)) tclas_t;
+
+
+#define CONFIG_IND_ERROR 0x01
+#define CONFIG_IND_EXIT 0x02
+#define CONFIG_SME_NOT_PRESENT 0x10
+#define CONFIG_SME_PRESENT 0x20
+
+#endif /* __UNIFIIO_H__ */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/wext_events.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/wext_events.c
new file mode 100644
index 0000000..4d52003
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/driver/wext_events.c
@@ -0,0 +1,251 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: wext_events.c
+ *
+ * PURPOSE:
+ * Code to generate iwevents.
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <linux/types.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include "driver/unifi.h"
+#include "unifi_priv.h"
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * wext_send_assoc_event
+ *
+ * Send wireless-extension events up to userland to announce
+ * successful association with an AP.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ * bssid MAC address of AP we associated with
+ * req_ie, req_ie_len IEs in the original request
+ * resp_ie, resp_ie_len IEs in the response
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * This is sent on first successful association, and again if we
+ * roam to another AP.
+ * ---------------------------------------------------------------------------
+ */
+void
+wext_send_assoc_event(unifi_priv_t *priv, unsigned char *bssid,
+ unsigned char *req_ie, int req_ie_len,
+ unsigned char *resp_ie, int resp_ie_len,
+ unsigned char *scan_ie, unsigned int scan_ie_len)
+{
+#if WIRELESS_EXT > 17
+ union iwreq_data wrqu;
+
+#if 0
+ printk("wext_send_assoc_event: %p, %p, %p, %d, %p, %d\n",
+ priv, bssid,
+ req_ie, req_ie_len,
+ resp_ie, resp_ie_len);
+#endif
+
+ if (req_ie_len == 0) req_ie = NULL;
+ wrqu.data.length = req_ie_len;
+ wrqu.data.flags = 0;
+ wireless_send_event(priv->netdev, IWEVASSOCREQIE, &wrqu, req_ie);
+
+ if (resp_ie_len == 0) resp_ie = NULL;
+ wrqu.data.length = resp_ie_len;
+ wrqu.data.flags = 0;
+ wireless_send_event(priv->netdev, IWEVASSOCRESPIE, &wrqu, resp_ie);
+
+ if (scan_ie_len > 0) {
+ wrqu.data.length = scan_ie_len;
+ wrqu.data.flags = 0;
+ wireless_send_event(priv->netdev, IWEVGENIE, &wrqu, scan_ie);
+ }
+
+ memcpy(&wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu, NULL);
+#endif
+} /* wext_send_assoc_event() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * wext_send_disassoc_event
+ *
+ * Send a wireless-extension event up to userland to announce
+ * that we disassociated from an AP.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * The semantics of wpa_supplicant (the userland SME application) are
+ * that a SIOCGIWAP event with MAC address of all zero means
+ * disassociate.
+ * ---------------------------------------------------------------------------
+ */
+void
+wext_send_disassoc_event(unifi_priv_t *priv)
+{
+#if WIRELESS_EXT > 17
+ union iwreq_data wrqu;
+
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu, NULL);
+#endif
+} /* wext_send_disassoc_event() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * wext_send_scan_results_event
+ *
+ * Send wireless-extension events up to userland to announce
+ * completion of a scan.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ *
+ * Returns:
+ * None.
+ *
+ * Notes:
+ * This doesn't actually report the results, they are retrieved
+ * using the SIOCGIWSCAN ioctl command.
+ * ---------------------------------------------------------------------------
+ */
+void
+wext_send_scan_results_event(unifi_priv_t *priv)
+{
+#if WIRELESS_EXT > 17
+ union iwreq_data wrqu;
+
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu, NULL);
+
+#endif
+} /* wext_send_scan_results_event() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * wext_send_michaelmicfailure_event
+ *
+ * Send wireless-extension events up to userland to announce
+ * completion of a scan.
+ *
+ * Arguments:
+ * priv Pointer to driver context.
+ * count, macaddr, key_type, key_idx, tsc
+ * Parameters from report from UniFi.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+#if WIRELESS_EXT >= 18
+static inline void
+_send_michaelmicfailure_event(struct net_device *dev,
+ int count, const unsigned char *macaddr,
+ int key_type, int key_idx,
+ unsigned char *tsc)
+{
+ union iwreq_data wrqu;
+ struct iw_michaelmicfailure mmf;
+
+ /* TODO: needed parameters: count, keyid, key type, TSC */
+ memset(&mmf, 0, sizeof(mmf));
+
+ mmf.flags = key_idx & IW_MICFAILURE_KEY_ID;
+ if (key_type == CSR_GROUP) {
+ mmf.flags |= IW_MICFAILURE_GROUP;
+ } else {
+ mmf.flags |= IW_MICFAILURE_PAIRWISE;
+ }
+ mmf.flags |= ((count << 5) & IW_MICFAILURE_COUNT);
+
+ mmf.src_addr.sa_family = ARPHRD_ETHER;
+ memcpy(mmf.src_addr.sa_data, macaddr, ETH_ALEN);
+
+ memcpy(mmf.tsc, tsc, IW_ENCODE_SEQ_MAX_SIZE);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = sizeof(mmf);
+
+ wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&mmf);
+}
+#elif WIRELESS_EXT >= 15
+static inline void
+_send_michaelmicfailure_event(struct net_device *dev,
+ int count, const unsigned char *macaddr,
+ int key_type, int key_idx,
+ unsigned char *tsc)
+{
+ union iwreq_data wrqu;
+ char buf[128];
+
+ /* TODO: needed parameters: count, keyid, key type, TSC */
+ unifi_sprintf(buf,
+ "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=%02x:%02x:%02x:%02x:%02x:%02x)",
+ key_idx, (key_type == CSR_GROUP) ? "broad" : "uni",
+ macaddr[0], macaddr[1], macaddr[2],
+ macaddr[3], macaddr[4], macaddr[5]);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = strlen(buf);
+ wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
+}
+#else /* WIRELESS_EXT >= 15 */
+static inline void
+_send_michaelmicfailure_event(struct net_device *dev,
+ int count, const unsigned char *macaddr,
+ int key_type, int key_idx,
+ unsigned char *tsc)
+{
+ /* Not supported before WEXT 15 */
+}
+#endif /* WIRELESS_EXT >= 15 */
+
+
+void
+wext_send_michaelmicfailure_event(unifi_priv_t *priv,
+ const CSR_MLME_MICHAELMICFAILURE_INDICATION *ind)
+{
+ unsigned char tsc[8];
+
+ /* tsc in IWEVMICHAELMICFAILURE event is defined to be LSB first */
+ tsc[0] = ind->Tsc & 0xFF;
+ tsc[1] = (ind->Tsc >> 8) & 0xFF;
+ tsc[2] = (ind->Tsc >> 16) & 0xFF;
+ tsc[3] = (ind->Tsc >> 24) & 0xFF;
+ tsc[4] = (ind->Tsc >> 32) & 0xFF;
+ tsc[5] = (ind->Tsc >> 40) & 0xFF;
+ tsc[6] = (ind->Tsc >> 48) & 0xFF;
+ tsc[7] = (ind->Tsc >> 56) & 0xFF;
+ _send_michaelmicfailure_event(priv->netdev,
+ ind->Count,
+ ind->Address.x,
+ ind->KeyType,
+ ind->KeyId,
+ tsc);
+} /* wext_send_michaelmicfailure_event() */
+
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/scripts/fc4install b/unifi_hostsw_linux_147/unifi-linux/os_linux/scripts/fc4install
new file mode 100755
index 0000000..65e3ba4
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/scripts/fc4install
@@ -0,0 +1,107 @@
+#!/bin/bash
+# Copyright (C) 2005-2007 by Cambridge Silicon Radio Ltd.
+#
+# Script to install UniFi driver on a Fedora Core 4 system
+#
+
+scriptdir=`dirname $0`
+topdir=`cd $scriptdir/../..; pwd`
+
+# Go to top of linux driver tree
+cd $topdir
+
+# Extract kernel info
+kver=`uname -r`
+instroot=/lib/modules/$kver/kernel
+
+
+#
+# Remove any old Arasan modules
+#
+grep -q -e "^sdhcd\b" /proc/modules && /sbin/modprobe --remove sdhcd
+grep -q -e "^sdcore\b" /proc/modules && /sbin/modprobe --remove sdcore
+
+#
+# Remove any old driver files and helper progs
+#
+oldfilelist="\
+${instroot}/drivers/sdio/sdhcd.ko
+${instroot}/drivers/sdio/sdcore.ko
+${instroot}/drivers/net/wireless/unifi_sdio.ko
+/usr/sbin/unifidl
+/usr/sbin/unifimib
+"
+for f in $oldfilelist; do
+ if [ -f $f ]; then
+ echo " deleting $f"
+ rm $f
+ fi
+done
+
+#
+# Install driver and tools
+#
+SDIODIR=$topdir/../sdioemb ./os_linux/driver/build generic install
+/sbin/depmod
+
+
+#
+# Add CSR UniFi to module-info for system-config-network tool,
+# if not already there.
+#
+grep -q unifi_sdio /usr/share/system-config-network/module-info || \
+cat >>/usr/share/system-config-network/module-info <<EOF
+
+unifi_sdio
+ eth
+ "CSR UniFi SDIO"
+EOF
+
+
+# Device nodes are created when needed by unififw script
+
+
+#
+# Install new firmware, if provided
+#
+if [ -d firmware ]; then
+
+ [ -d /lib/firmware/unifi-sdio-0 ] || mkdir -p /lib/firmware/unifi-sdio-0
+
+ cp -a firmware/dev-pc* /lib/firmware
+
+ if [ -h /lib/firmware/unifi-sdio-0/sta.xbv ]; then
+ echo "Detected symbolic link to the firmware. New firmware will not be installed."
+ else
+ cp -a firmware/sta.xbv /lib/firmware/unifi-sdio-0/
+ echo "New firmware installed in /lib/firmware/unifi-sdio-0."
+ fi
+ if [ -h /lib/firmware/unifi-sdio-0/loader.xbv ]; then
+ echo "Detected symbolic link to the loader. New loader will not be installed."
+ else
+ cp -a firmware/loader.xbv /lib/firmware/unifi-sdio-0/
+ echo "New loader installed in /lib/firmware/unifi-sdio-0."
+ fi
+
+ if [ ! -f /lib/firmware/unifi-sdio-0/mac.txt ]; then
+ echo
+ echo -n "Enter a MAC address for UniFi (e.g. 00:02:5b:00:01:02):"
+ read mac
+ echo $mac >/lib/firmware/unifi-sdio-0/mac.txt
+ fi
+ echo
+ echo "If UniFi requires a MIB file, install ufmib.dat in /lib/firmware/unifi-sdio-0"
+fi
+
+
+#
+# Reload the driver
+#
+killall -q -w unifi_manager
+killall -q -w unifi_helper
+grep -q -e "^unifi_sdio\b" /proc/modules && /sbin/modprobe --remove unifi_sdio
+grep -q -e "^slot_shc\b" /proc/modules && /sbin/modprobe --remove slot_shc
+grep -q -e "^sdio\b" /proc/modules && /sbin/modprobe --remove sdio
+grep -q -e "^oska\b" /proc/modules && /sbin/modprobe --remove oska
+/sbin/modprobe slot_shc
+/sbin/modprobe unifi_sdio
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/Makefile b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/Makefile
new file mode 100644
index 0000000..1723449
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/Makefile
@@ -0,0 +1,62 @@
+# -----------------------------------------------------------------------------
+#
+# FILE: Makefile
+#
+# Build instructions for unifimib and unifidl.
+#
+# HISTORY:
+# 22-Nov-05 MEDP Use $CROSS_COMPILE prefix for tools.
+# 05-Oct-05 MEDP Build unifidl too.
+# 02-Sep-05 MEDP Creation
+# -----------------------------------------------------------------------------
+
+CC := $(CROSS_COMPILE)gcc
+
+CFLAGS := -I../../common -I../driver -I../../lib_sme/common -Wall -g -O2
+LDFLAGS := -g
+
+UM_OBJS := unifi_manager.o mibquery.o sme_drv.o
+
+UF_CFG_OBJS := unifi_config_lib.o unifi_config.o
+
+UF_PUTEST_OBJS := unifi_putest_lib.o unifi_putest.o
+
+GSMIB_OBJS := mibquery.o unifi_mib.o
+
+SBINDIR := /usr/sbin
+
+PROGS := unifi_manager unifi_config
+SCRIPTS := unififw
+
+# Local tools not for distribution
+TOOLS := genmacmib prmib unifi_qos unifi_mib unifi_putest
+
+all: $(PROGS) $(TOOLS)
+
+unifi_manager: $(UM_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(UM_OBJS)
+
+
+genmacmib: genmacmib.o
+ $(CC) $(LDFLAGS) -o $@ genmacmib.o
+
+prmib: prmib.o
+ $(CC) $(LDFLAGS) -o $@ prmib.o
+
+unifi_qos: unifi_qos.o
+ $(CC) $(LDFLAGS) -o $@ unifi_qos.o
+
+unifi_config: $(UF_CFG_OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(UF_CFG_OBJS)
+
+unifi_putest: $(UF_PUTEST_OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(UF_PUTEST_OBJS)
+
+unifi_mib: $(GSMIB_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(GSMIB_OBJS)
+
+install: $(PROGS)
+ for p in $(PROGS) $(SCRIPTS); do install -D $$p $(DESTDIR)$(SBINDIR)/$$p; done
+
+clean:
+ rm -f *.o $(PROGS) genmacmib prmib unifi_qos unifi_mib unifi_config unifi_putest
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/README b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/README
new file mode 100644
index 0000000..8531318
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/README
@@ -0,0 +1,11 @@
+This directory contains the "unifidl" and "unifimib" tools.
+
+Unifidl downloads f/w to a RAM-only UniFi.
+
+Unifimib sets MIB entries.
+
+MIB entries may be set at any time, but the primary use is for setting the
+initial MIB contents.
+
+The tools use ioctl commands defined in unifiio.h.
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/getsubopt.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/getsubopt.c
new file mode 100644
index 0000000..45b65da
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/getsubopt.c
@@ -0,0 +1,92 @@
+/*
+ * Android c-library does not have getsubopt,
+ * so code lifted from uClibc
+ * http://git.uclibc.org/uClibc/tree/libc/unistd/getsubopt.c
+ */
+
+/* Parse comma separate list into words.
+ Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+char *strchrnul(const char *s, int c)
+{
+ char *result;
+
+ result = strchr( s, c );
+
+ if( !result )
+ {
+ result = (char *)s + strlen( s );
+ }
+
+ return( result );
+}
+
+/* Parse comma separated suboption from *OPTIONP and match against
+ strings in TOKENS. If found return index and set *VALUEP to
+ optional value introduced by an equal sign. If the suboption is
+ not part of TOKENS return in *VALUEP beginning of unknown
+ suboption. On exit *OPTIONP is set to the beginning of the next
+ token or at the terminating NUL character. */
+int
+getsubopt (char **optionp, char *const *tokens, char **valuep)
+{
+ char *endp, *vstart;
+ int cnt;
+
+ if (**optionp == '\0')
+ return -1;
+
+ /* Find end of next token. */
+ endp = strchrnul (*optionp, ',');
+
+ /* Find start of value. */
+ vstart = memchr (*optionp, '=', endp - *optionp);
+ if (vstart == NULL)
+ vstart = endp;
+
+ /* Try to match the characters between *OPTIONP and VSTART against
+ one of the TOKENS. */
+ for (cnt = 0; tokens[cnt] != NULL; ++cnt)
+ if (strncmp (*optionp, tokens[cnt], vstart - *optionp) == 0
+ && tokens[cnt][vstart - *optionp] == '\0')
+ {
+ /* We found the current option in TOKENS. */
+ *valuep = vstart != endp ? vstart + 1 : NULL;
+
+ if (*endp != '\0')
+ *endp++ = '\0';
+ *optionp = endp;
+
+ return cnt;
+ }
+
+ /* The current suboption does not match any option. */
+ *valuep = *optionp;
+
+ if (*endp != '\0')
+ *endp++ = '\0';
+ *optionp = endp;
+
+ return -1;
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/hotplug b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/hotplug
new file mode 100644
index 0000000..51945d5
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/hotplug
@@ -0,0 +1,52 @@
+#!/system/bin/sh
+
+LOG="/system/bin/log -p d HOTPLUG "
+
+$LOG $SUBSYSTEM Action $ACTION
+
+
+case "$SUBSYSTEM" in
+ firmware)
+
+ case "$ACTION" in
+ add)
+
+ $LOG blah $SUBSYSTEM Action $ACTION
+
+ HOTPLUG_FW_DIR=/system/etc/firmware
+
+ if ! /system/bin/ls /sys$DEVPATH/loading; then
+ $LOG "FIRMWARE - /sys$DEVPATH/loading does not exist"
+ exit 1
+ fi
+
+ if ! /system/bin/ls $HOTPLUG_FW_DIR/$FIRMWARE; then
+ $LOG "FIRMWARE $HOTPLUG_FW_DIR/$FIRMWARE does not exist"
+ $(/system/bin/sh -c "echo -1 > /sys$DEVPATH/loading")
+ exit 1
+ fi
+
+ $LOG "$SUBSYSTEM starting fw download $HOTPLUG_FW_DIR/$FIRMWARE"
+
+ check_loading=$(/system/bin/cat /sys$DEVPATH/loading)
+
+ case "$check_loading" in
+ 0)
+ $(/system/bin/sh -c "echo 1 > /sys$DEVPATH/loading")
+ ;;
+
+ 1)
+ exit 1
+ ;;
+ esac
+
+ $(/system/bin/cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys$DEVPATH/data)
+ $(/system/bin/sh -c "echo 0 > /sys$DEVPATH/loading")
+ exit 0
+
+ ;;
+ esac
+ ;;
+esac
+
+exit 0
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/unififw b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/unififw
new file mode 100644
index 0000000..7310d77
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/android/unififw
@@ -0,0 +1,79 @@
+#!/system/bin/sh
+# Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
+# /system/bin/unififw
+# This is run from the driver via kerneld when a UniFi card
+# is inserted.
+#
+
+# Set up the uevent helper script
+# Has to be done this way to stop all output from this script being
+# piped to uevent_helper, and echo is a builtin, so $(echo blah) does
+# not work!
+#
+# New android releases have a firmware helper script, DO NOT SET THIS
+#$(/system/bin/sh -c "echo /system/bin/hotplug > /sys/kernel/uevent_helper")
+
+# Find files for:
+# ufmib.dat - standard MIB for the h/w
+# mac.txt - MAC address (in text format)
+
+instance="$1"
+
+init_mode="$2"
+
+fwpath=/system/etc/firmware/unifi-sdio-$instance
+
+case "$init_mode" in
+ 2)
+ mibfileparam=""
+ if /system/bin/ls $fwpath/ufmib.dat; then
+ mibfileparam="-mib=$fwpath/ufmib.dat"
+ fi
+
+ macfileparam=""
+ if /system/bin/ls $fwpath/mac.txt; then
+ macfileparam="-mac=$fwpath/mac.txt"
+ fi
+
+ /system/bin/unifi_helper -dev=/dev/unifi$instance -wifion $macfileparam $mibfileparam &
+ helper_pid=$!
+ /system/bin/setprop wlan.driver.helper_pid $helper_pid
+ wait $helper_pid
+ /system/bin/setprop wlan.driver.helper_pid 0
+ /system/bin/setprop wlan.driver.status "failed"
+ /system/bin/rmmod unifi_sdio
+ exit 0
+esac
+
+# unifi_manager mode
+
+# This is a bit of a hack. When we have no firmware, sometimes when we
+# run unifi_manager the device nodes are not there yet, and it fails.
+# I guess this is some sort of a race, but I odn't know how to fix it.
+sleep 0.25
+
+# Set the MAC address, MIB(s) and start the driver.
+
+# Fallback to the broadcast MAC addr, which UniFi takes to mean "use the
+# MAC address from MIB", typically read from EEPROM
+macaddr="FF:FF:FF:FF:FF:FF"
+if /system/bin/ls $fwpath/mac.txt; then
+ macaddr=$(/system/bin/cat $fwpath/mac.txt)
+fi
+
+mibfile=""
+if /system/bin/ls $fwpath/ufmib.dat; then
+ mibfile="$fwpath/ufmib.dat"
+fi
+
+/system/bin/unifi_manager -d /dev/unifi$instance -s $macaddr -b $init_mode $mibfile &
+helper_pid=$!
+/system/bin/setprop wlan.driver.helper_pid $helper_pid
+# FIXME TBD
+/system/bin/sleep 4
+/system/bin/setprop wlan.driver.status "ok"
+wait $helper_pid
+/system/bin/setprop wlan.driver.helper_pid 0
+/system/bin/setprop wlan.driver.status "failed"
+/system/bin/rmmod unifi_sdio
+exit 0
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/genmacmib.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/genmacmib.c
new file mode 100644
index 0000000..d70ce6b
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/genmacmib.c
@@ -0,0 +1,291 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: genmacmib.c
+ *
+ * Program to generate a MIB file containing a single entry to
+ * set the chip MAC address.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ctype.h>
+
+int read_mac(char *arg, unsigned char *macaddr);
+
+
+static void output_mib(unsigned char *macaddr, FILE *fp);
+static void output_raw(unsigned char *macaddr, FILE *fp);
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * main
+ *
+ * C entry point
+ *
+ * Arguments:
+ * argc, argv command line args
+ *
+ * Returns:
+ * exit code
+ * ---------------------------------------------------------------------------
+ */
+int
+main(int argc, char *argv[])
+{
+ unsigned char macaddr[6];
+ int mib = 0;
+ char *outfile = "mac.dat";
+ FILE *fp;
+ int c, err;
+
+
+ err = 0;
+ while ((c=getopt(argc, argv, "bmo:")) != -1)
+ {
+ switch (c) {
+ case 'b':
+ mib = 0;
+ break;
+ case 'm':
+ mib = 1;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ default:
+ err++;
+ }
+ }
+
+
+ if (optind >= argc) {
+ fprintf(stderr, "Expected MAC address\n");
+ err++;
+ }
+ if (err) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " genmacmib [options] xx:xx:xx:xx:xx:xx\n");
+ fprintf(stderr, " Generate a binary containing the given MAC address\n");
+ fprintf(stderr, " The file can be raw binary or a UniFi MIB\n");
+ fprintf(stderr, " Options:\n");
+ fprintf(stderr, " -b Generate a raw binary file (default)\n");
+ fprintf(stderr, " -m Generate a MIB file\n");
+ fprintf(stderr, " -o file Send output to file\n");
+ exit(1);
+ }
+
+ if (read_mac(argv[optind], macaddr)) {
+ fprintf(stderr, "Badly formatted MAC address\n");
+ exit(1);
+ }
+
+ if (outfile) {
+ fp = fopen(outfile, "w");
+ if (!fp) {
+ perror("Failed to open output file");
+ exit(2);
+ }
+ } else {
+ fprintf(stderr, "Unspecified Output file.\n");
+ exit(1);
+ }
+
+ if (mib) {
+ output_mib(macaddr, fp);
+ } else {
+ output_raw(macaddr, fp);
+ }
+
+ if (outfile) {
+ fclose(fp);
+ }
+
+ return 0;
+} /* main() */
+
+
+
+static void
+output_mib(unsigned char *macaddr, FILE *fp)
+{
+ /* Output the header */
+ putc('U', fp);
+ putc('D', fp);
+ putc('M', fp);
+ putc('I', fp);
+
+ /* Output the version */
+ putc(1, fp);
+ putc(0, fp);
+
+ /* total length following - 24 */
+ putc(24, fp);
+ putc(0, fp);
+ putc(0, fp);
+ putc(0, fp);
+
+ /* MIB length - 22 */
+ putc(0x16, fp);
+ putc(0, fp);
+
+ /* Sequence tag and len */
+ putc(0x30, fp);
+ putc(0x14, fp);
+
+ /* OID tag, len and value */
+ putc(0x06, fp);
+ putc(0x0a, fp);
+ putc(0x2a, fp);
+ putc(0x86, fp);
+ putc(0x48, fp);
+ putc(0xce, fp);
+ putc(0x34, fp);
+ putc(0x02, fp);
+ putc(0x01, fp);
+ putc(0x01, fp);
+ putc(0x01, fp);
+ putc(0x01, fp);
+
+ /* MAC addr: OCTETSTRING tag, len and value */
+ putc(0x04, fp);
+ putc(0x06, fp);
+ putc(macaddr[0], fp);
+ putc(macaddr[1], fp);
+ putc(macaddr[2], fp);
+ putc(macaddr[3], fp);
+ putc(macaddr[4], fp);
+ putc(macaddr[5], fp);
+} /* output_mib() */
+
+static void
+output_raw(unsigned char *macaddr, FILE *fp)
+{
+ putc(macaddr[0], fp);
+ putc(macaddr[1], fp);
+ putc(macaddr[2], fp);
+ putc(macaddr[3], fp);
+ putc(macaddr[4], fp);
+ putc(macaddr[5], fp);
+} /* output_raw() */
+
+
+int
+read_byte(char *p, unsigned char *b)
+{
+ int n = 0;
+ int i, c, v;
+
+ /* Use a loop so we accept single digit fields */
+ v = 0;
+ for (i = 0; i < 2; i++) {
+
+ c = *p++;
+
+ if ((c >= '0') && (c <= '9')) {
+ c -= '0';
+ } else if ((c >= 'A') && (c <= 'F')) {
+ c = c - 'A' + 10;
+ } else if ((c >= 'a') && (c <= 'f')) {
+ c = c - 'a' + 10;
+ } else {
+ break;
+ }
+
+ v = (v * 16) + c;
+ n++;
+ }
+
+ if (n) {
+ *b = v;
+ }
+
+ return n;
+} /* read_byte() */
+
+
+int
+is_delim(int ch)
+{
+ return ((ch == ':') || (ch == '.') || (ch == ','));
+} /* is_delim() */
+
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_mac
+ *
+ * Extract the MAC address from command line argument.
+ * The expected format is something like 00:00:5B:00:23:45, although
+ * '-' and ',' are also accepted as delimiters.
+ *
+ * Arguments:
+ * arg The command-line argument string
+ * macaddr Pointer to 6-byte array to receive decoded MAC address
+ *
+ * Returns:
+ * 0 on success, -1 if the string does not conform to expected format.
+ * ---------------------------------------------------------------------------
+ */
+int
+read_mac(char *arg, unsigned char *macaddr)
+{
+ char *p = arg;
+ int i, n;
+
+ i = 0;
+
+ n = read_byte(p, &macaddr[0]);
+ if (n == 0) return -1;
+ p += n;
+
+ if (!is_delim(*p)) return -1;
+ p++;
+
+ n = read_byte(p, &macaddr[1]);
+ if (n == 0) return -1;
+ p += n;
+
+ if (!is_delim(*p)) return -1;
+ p++;
+
+ n = read_byte(p, &macaddr[2]);
+ if (n == 0) return -1;
+ p += n;
+
+ if (!is_delim(*p)) return -1;
+ p++;
+
+ n = read_byte(p, &macaddr[3]);
+ if (n == 0) return -1;
+ p += n;
+
+ if (!is_delim(*p)) return -1;
+ p++;
+
+ n = read_byte(p, &macaddr[4]);
+ if (n == 0) return -1;
+ p += n;
+
+ if (!is_delim(*p)) return -1;
+ p++;
+
+ n = read_byte(p, &macaddr[5]);
+ if (n == 0) return -1;
+ p += n;
+
+ if (*p != '\0') return -1;
+
+ return 0;
+} /* read_mac() */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/mibquery.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/mibquery.c
new file mode 100644
index 0000000..16b65cd
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/mibquery.c
@@ -0,0 +1,421 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: mibquery.c
+ *
+ * Code for querying a MIB value from UniFi.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include "sme_drv.h"
+#include "unifiio.h"
+
+
+#define MIB_TAG_BOOLEAN 0x01
+#define MIB_TAG_INTEGER 0x02
+#define MIB_TAG_OCTETSTRING 0x04
+#define MIB_TAG_NULL 0x05
+#define MIB_TAG_OID 0x06
+#define MIB_TAG_SEQUENCE 0x30
+
+
+
+/*
+ * MibEncodeVarBindInt
+ */
+static int
+MibEncodeVarBindInt(int aInt, unsigned char *aData)
+{
+ int bytesWritten;
+ unsigned char value[4];
+ int i;
+
+ for (bytesWritten = 0; bytesWritten < 4; aInt /= 128)
+ {
+ value[bytesWritten] = (unsigned char)(aInt % 128);
+ ++bytesWritten;
+
+ if (aInt <= 127)
+ {
+ break;
+ }
+ }
+
+ for (i = bytesWritten - 1; i >= 0; --i, ++aData)
+ {
+ *aData = value[i];
+ if (i > 0)
+ {
+ *aData += 0x80;
+ }
+ }
+
+ return bytesWritten;
+} /* MibEncodeVarBindInt() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_decimal
+ *
+ * Scan a string for digits. Convert the digits (up to a non-digit
+ * delimiter) into a decimal number.
+ *
+ * Arguments:
+ * s String to scan
+ * val Pointer to which to write the result
+ *
+ * Returns:
+ * NUmber of characters used.
+ * ---------------------------------------------------------------------------
+ */
+#define isdigit(_c) (((_c) >= '0') && ((_c) <= '9'))
+static int
+read_decimal(const char *s, int *val)
+{
+ const char *p = s;
+ int v = 0;
+
+ /* Convert the number */
+ while (*p && isdigit(*p)) {
+ v = (v * 10) + *p - '0';
+ p++;
+ }
+
+ *val = v;
+
+ return p - s;
+} /* read_int() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * MibEncodeOID
+ *
+ * Encode an OID (given as a string of dotted numbers, e.g. 1.2.840.1)
+ * into ASN.1 BER.
+ *
+ * Arguments:
+ * oid_str OID string to convert
+ * buf Pointer to buffer to write encoding into
+ *
+ * Returns:
+ * number of bytes written to buf.
+ *
+ * Notes:
+ * This function makes the following assumptions:
+ * 1) The contents field will be no longer than 127 octets when encoded.
+ * ---------------------------------------------------------------------------
+ */
+int
+MibEncodeOID(const char *oid_str, unsigned char *buf)
+{
+ int length = 0;
+ unsigned char *data = buf;
+ const char *p;
+ int id, tmp;
+ int i;
+
+ buf[0] = MIB_TAG_OID;
+
+ p = oid_str;
+ data = buf + 2; /* Assuming length will always be 1 octet */
+ i = 0;
+ while (*p)
+ {
+ /* Read integer from string */
+ p += read_decimal(p, &id);
+ if (*p) p++; /* step over separator */
+
+ switch (i)
+ {
+ case 0:
+ *data = 40 * id;
+ length++;
+ break;
+ case 1:
+ *data += id;
+ data++;
+ break;
+ default:
+ tmp = MibEncodeVarBindInt(id, data);
+ length += tmp;
+ data += tmp;
+ break;
+ }
+ i++;
+ }
+
+ buf[1] = (unsigned char)length;
+
+ return 2 + length;
+} /* MibEncodeOID() */
+
+
+/*
+ * MibEncodeNull
+ */
+int
+MibEncodeNull(unsigned char *aData)
+{
+ aData[0] = MIB_TAG_NULL;
+ aData[1] = 0;
+
+ return 2;
+} /* MibEncodeNull() */
+
+
+/*
+ * ******************************************************************************
+ * MibEncodeBoolean -
+ *
+ * PARAMETERS
+ * aVal - Boolean value to encode (0 = FALSE, 1 = TRUE).
+ * aData - Pointer to buffer to decode.
+ *
+ * RETURNS
+ * Number of bytes written into buffer pointed to by aData.
+ *
+ */
+int
+MibEncodeBoolean(int aVal, unsigned char *aData)
+{
+ aData[0] = MIB_TAG_BOOLEAN;
+ aData[1] = 1;
+ aData[2] = aVal;
+
+ return 3;
+}
+
+
+/*
+ * ******************************************************************************
+ * MibEncodeInteger -
+ *
+ * RETURNS
+ * Number of bytes written into buffer pointed to by aData.
+ *
+ */
+int
+MibEncodeInteger(int aVal, unsigned char *aData)
+{
+ int length = 0;
+ unsigned char valBytes[5] = { 0, 0, 0, 0, 0 };
+ unsigned char *data = aData;
+ int val = aVal;
+ int i;
+
+ *data = MIB_TAG_INTEGER;
+ data += 2; /* Assuming length will always be 1 octet */
+
+ do
+ {
+ if(val == 0)
+ {
+ *data = 0;
+ length = 1;
+ break;
+ }
+
+ while((val != 0) && (length < 4))
+ {
+ valBytes[length] = (val & 0xff);
+ ++length;
+ if((val < -128) || (val > 127))
+ {
+ val >>= 8;
+ }
+ else
+ {
+ /* Ensures we only use the minimum number of contents octets */
+ val = 0;
+ }
+ }
+
+ if((aVal > 0) && (valBytes[length - 1] & 0x80))
+ {
+ valBytes[length] = 0;
+ ++length;
+ }
+
+ for(i = length - 1; i >= 0; --i)
+ {
+ *data = valBytes[i]; ++data;
+ }
+ }
+ while(0);
+
+ aData[1] = (unsigned char)length;
+
+ return 2 + length;
+}
+
+
+
+/*
+ * ******************************************************************************
+ * MibEncodeOctetString -
+ *
+ * PARAMETERS
+ * aStrLength - Number of bytes pointed to by aStr (<= 255).
+ * aStr - Pointer to an array of bytes to include in the octet string.
+ * aData - Pointer to buffer to encode octet string into.
+ *
+ * RETURNS
+ * Number of bytes written into buffer pointed to by aData.
+ *
+ * REMARKS
+ * This encoding is always primitive.
+ *
+ */
+int
+MibEncodeOctetString(unsigned char *aStr, int aStrLength, unsigned char *aData)
+{
+ unsigned char *data = aData;
+ unsigned char *inData = aStr;
+ int i;
+
+ *data = MIB_TAG_OCTETSTRING;
+ data += 2; /* Assuming length will always be 1 octet */
+
+ for(i = 0; i < aStrLength; ++i, ++data, ++inData)
+ {
+ *data = *inData;
+ }
+
+ aData[1] = (unsigned char)aStrLength;
+
+ return 2 + aStrLength;
+}
+
+
+
+
+/*
+ * ******************************************************************************
+ * MibDecodeInteger -
+ *
+ * PARAMETERS
+ * aData -
+ * aVal - Pointer to integer to contain decoded value.
+ *
+ * RETURNS
+ * Number of bytes read from aData.
+ *
+ * REMARKS
+ * This function will only decode up to 32-bit integers.
+ *
+ */
+int
+MibDecodeInteger(unsigned char *aData, int *aVal)
+{
+ unsigned char *data = aData + 2;
+ int nbytes;
+ int i = 0;
+ int u;
+
+ if(aData[0] != MIB_TAG_INTEGER)
+ {
+ return 0;
+ }
+
+ nbytes = aData[1];
+ if (nbytes > 4)
+ {
+ return 0;
+ }
+
+ if (nbytes == 0)
+ {
+ *aVal = 0;
+ }
+
+ u = (data[0] & 0x80) ? -1 : 0;
+
+ for (i = 0; i < nbytes; i++)
+ {
+ u = (u << 8) | data[i];
+ }
+ *aVal = u;
+
+ return nbytes;
+} /* MibDecodeInteger() */
+
+/*
+ * ******************************************************************************
+ * MibDecodeOctetString -
+ *
+ * PARAMETERS
+ * aData - Octet string to decode.
+ * aStrLength - Number of bytes in buffer pointed to by aData.
+ * aStr - Pointer to buffer to decode octet string to.
+ *
+ * RETURNS
+ * Number of bytes read from aOctStr.
+ *
+ */
+int
+MibDecodeOctetString(unsigned char *aData, int aStrLength, unsigned char *aStr)
+{
+ int length;
+ unsigned char *inData = aData + 2;
+ unsigned char *data = aStr;
+ int maxlen;
+
+ if (aData[0] != MIB_TAG_OCTETSTRING)
+ {
+ return 0;
+ }
+
+ /* maxlen = min(aStrLength, aData[1]); */
+ maxlen = aStrLength;
+ if (maxlen > aData[1]) maxlen = aData[1];
+
+ for (length = 0; length < maxlen; ++length, ++data, ++inData)
+ {
+ *data = *inData;
+ }
+
+ return length;
+}
+
+/*
+ * ******************************************************************************
+ * MibDecodeBoolean -
+ *
+ * PARAMETERS
+ * aData - Pointer to buffer to decode.
+ * aVal - Pointer to boolean value to decode into.
+ *
+ * RETURNS
+ * Returns 1 if successfully decoded, otherwise 0.
+ *
+ */
+int
+MibDecodeBoolean(unsigned char *aData, uint32 *aVal)
+{
+ if(aData[0] != MIB_TAG_BOOLEAN)
+ {
+ return 0;
+ }
+
+ if(aData[1] != 1)
+ {
+ return 0;
+ }
+
+ *aVal = aData[2];
+
+ return 1;
+}
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/prmib.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/prmib.c
new file mode 100644
index 0000000..2272294
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/prmib.c
@@ -0,0 +1,287 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: prmib.c
+ *
+ * PURPOSE:
+ * This file provides functions to send MLME requests to the UniFi.
+ * It is OS-independent.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+static int process_mib_file(const char *mib_file);
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * main
+ *
+ * C entry point
+ *
+ * Arguments:
+ * argc, argv command line args
+ *
+ * Returns:
+ * exit code
+ * ---------------------------------------------------------------------------
+ */
+int
+main(int argc, char *argv[])
+{
+ const char *filename;
+
+ if (argc < 2) {
+ fprintf(stderr, "No filename given\n");
+ exit(1);
+ }
+
+
+ filename = argv[1];
+
+ if (process_mib_file(filename)) {
+ exit(1);
+ }
+
+
+ return 0;
+} /* main() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * print_varbind
+ *
+ * Print out the MIB setting.
+ *
+ * Arguments:
+ * varbind The encoded MIB entry.
+ * vblen Length of the encoded MIB entry.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static void
+print_varbind(unsigned char *varbind, int vblen)
+{
+ unsigned char *p = varbind;
+ int i;
+ int tag, len, val;
+
+// printf("0x%02X (%d)\n", p[0], p[1]);
+ p += 2;
+ vblen -= 2;
+
+ tag = p[0];
+ len = p[1];
+ p += 2;
+ vblen -= 2;
+// printf(" 0x%02X (%d)\n", tag, len);
+// printf(" ");
+ printf("%d.%d", *p / 40, *p % 40);
+ val = 0;
+ for (i = 1; i < len; i++) {
+ val = (val * 128) + (p[i] & 127);
+ if ((p[i] & 0x80) == 0) {
+ printf(".%d", val);
+ val = 0;
+ }
+ }
+ printf("\t");
+ p += len;
+
+ tag = p[0];
+ len = p[1];
+ p += 2;
+ vblen -= 2;
+// printf(" 0x%02X (%d)\n", tag, len);
+// printf(" ");
+ if (tag == 4) {
+ printf("0x");
+ for (i = 0; i < len; i++) {
+ printf("%02X", p[i]);
+ }
+ printf("\n");
+ } else {
+ val = 0;
+ for (i = 0; i < len; i++) {
+ val = (val * 128) + (p[i] & 127);
+ }
+ printf("%d\n", val);
+ }
+
+} /* print_varbind() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * decode_mibs
+ *
+ * Parse a UniFi MIB data file and download the MIB settings to
+ * the UniFi chip.
+ *
+ * Arguments:
+ * mibdata Pointer to MIB data file content.
+ * miblen Number of bytes available at mibdata.
+ *
+ * Returns:
+ * 0 on success, error code on failure.
+ * ---------------------------------------------------------------------------
+ */
+static int
+decode_mibs(unsigned char *mibdata, int miblen)
+{
+ unsigned char *header;
+ int version;
+ int filelen;
+ unsigned char *varbind;
+
+ /* Check mibdata contains at least the file header (10) and one MIB (2) */
+ if (miblen < 12) {
+ fprintf(stderr, "Error: Invalid MIB file");
+ return -EINVAL;
+ }
+
+ /*
+ * Read file header.
+ */
+ header = mibdata;
+ mibdata += 10;
+
+ if ((header[0] != 'U') || (header[1] != 'D') ||
+ (header[2] != 'M') || (header[3] != 'I'))
+ {
+ fprintf(stderr, "Error: Bad header in MIB file");
+ return -EINVAL;
+ }
+ version = header[4] + (header[5] << 8);
+ filelen = header[6] + (header[7] << 8) +
+ (header[8] << 16) + (header[9] << 24);
+
+ /* Check file length from file against given file size */
+ if ((filelen + 10) != miblen) {
+ fprintf(stderr, "Warning: Length mismatch for MIB file, expected %d, got %d\n",
+ (filelen + 10), miblen);
+
+ /* Truncate filelen if necessary */
+ if ((filelen + 10) > miblen) {
+ filelen = miblen - 10;
+ }
+ }
+
+ /*
+ * Read and set MIBs
+ */
+ while (filelen > 2)
+ {
+ int datalen;
+ unsigned char *vblen;
+
+ /* Read length field */
+ vblen = mibdata;
+ mibdata += 2;
+ filelen -= 2;
+
+ datalen = (vblen[1] << 8) + vblen[0];
+ if (datalen > filelen) {
+ fprintf(stderr, "Error: End of file reached reading MIB\n");
+ return -EINVAL;
+ }
+
+ /* Now read the varbind itself */
+ varbind = mibdata;
+ mibdata += datalen;
+ filelen -= datalen;
+
+ /* Check */
+ if ((varbind[1] + 2) != datalen) {
+ fprintf(stderr, "Error: Malformed MIB entry, bad length (%d != %d)\n",
+ varbind[1] + 2, datalen);
+ return -EINVAL;
+ }
+
+ /* Useful for debugging MIB files */
+ print_varbind(varbind, datalen);
+
+ }
+
+ return 0;
+
+} /* decode_mibs() */
+
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * process_mib_file
+ *
+ * Read, decode and print out the given MIB data file.
+ *
+ * Arguments:
+ * mib_file Filename of MIB data file to open.
+ *
+ * Returns:
+ * 0 on success, -1 on error.
+ * ---------------------------------------------------------------------------
+ */
+static int
+process_mib_file(const char *mib_file)
+{
+ FILE *fp;
+ unsigned char *mib_data;
+ int data_len;
+ struct stat st;
+
+ if (stat(mib_file, &st)) {
+ perror("Failed to stat img file");
+ return -1;
+ }
+
+ data_len = st.st_size;
+
+ fp = fopen(mib_file, "r");
+ if (!fp) {
+ perror("Failed to open MIB file");
+ exit(1) ;
+ }
+
+ mib_data = (unsigned char *)malloc(data_len);
+ if (mib_data == NULL) {
+ perror("Failed to allocate memory for firmware");
+ fclose(fp);
+ return -1;
+ }
+
+ /* NB This assumes fread() will successfully read whole file in one call
+ */
+ if (fread(mib_data, 1, data_len, fp) != data_len) {
+ perror("Failed to read MIB file");
+ free(mib_data);
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+
+
+ decode_mibs(mib_data, data_len);
+
+ free(mib_data);
+
+ return 0;
+} /* process_mib_file() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.c
new file mode 100644
index 0000000..4b84a0c
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.c
@@ -0,0 +1,411 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: sme_drv.c
+ *
+ * PURPOSE:
+ * This file provides the implementation of the connection establishment
+ * between the SME SHIM layer and the unifi driver.
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "sme_drv.h"
+#include "unifiio.h"
+#include "driver/conversions.h"
+
+#define MIB_TAG_INTEGER 0x02
+#define MIB_TAG_OCTETSTRING 0x04
+#define MIB_TAG_OID 0x06
+#define MIB_TAG_SEQUENCE 0x30
+
+#define MAX_VARBIND_LENGTH 127
+#define dot11MACAddress_oid "1.2.840.10036.2.1.1.1.1"
+
+int
+wait_for_event(MANAGER_PRIV_DATA *priv, int signal_id)
+{
+ static unsigned char buffer[4096];
+ fd_set readfds;
+ int reply_len;
+ CSR_SIGNAL *reply_signal;
+
+ while (1) {
+ int r;
+ udi_msg_t *msg;
+ unsigned char *sigptr;
+ int signal_and_data;
+
+ FD_ZERO(&readfds);
+ FD_SET(priv->Fd, &readfds);
+
+ /* This will poll in the char device for an event. */
+ r = select(priv->Fd+1, &readfds, NULL, NULL, NULL);
+ if (r < 0) {
+ perror("Error from select");
+ return ERROR_IO_ERROR;
+ }
+
+ /* This read will obtain the indication. */
+ r = read(priv->Fd, buffer, 4096);
+ if (r < 0) {
+ perror("Error reading UDI msg");
+ return ERROR_IO_ERROR;
+ }
+
+ /* We get a udi_msg_t, and the signal is appended right after the structure. */
+ msg = (udi_msg_t *)buffer;
+ sigptr = (unsigned char *)(msg + 1);
+
+ /* Total length of signal body + any bulk data */
+ signal_and_data = UNPACK32(buffer, offsetof(udi_msg_t, length)) - sizeof(udi_msg_t);
+
+ /*
+ * Check if the indication is actual a config indication,
+ * rather than a signal..
+ */
+ if (UNPACK32(buffer, offsetof(udi_msg_t, direction)) == UDI_CONFIG_IND) {
+ /* .. in this case the information is just one byte. */
+ return (int)(*sigptr);
+ }
+
+ reply_len = signal_and_data;
+ if (reply_len > 0) {
+ reply_signal = (CSR_SIGNAL*)sigptr;
+ if (signal_id == GET_SIGNAL_ID(sigptr)) {
+ if (signal_id == CSR_MLME_GET_CONFIRM_ID) {
+ unsigned char varbind[32];
+ unsigned char *ptr;
+ int oid_len;
+ const int oid_offset = offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_CONFIRM) + 2;
+
+ /* We are looking for this pattern. */
+ oid_len = MibEncodeOID(dot11MACAddress_oid, varbind);
+ /* Length of the signal with bulk data should be at least.. */
+ if (reply_len >= oid_offset + oid_len + 2 + 6) {
+ /* .. and the pattern should match. */
+ if (memcmp(sigptr + oid_offset, varbind, oid_len) == 0) {
+ ptr = sigptr + oid_offset + oid_len;
+ if ((ptr[0] == MIB_TAG_OCTETSTRING) && (ptr[1] == 6)) {
+ /* Store the MAC address, skip two bytes of the NULL decode. */
+ memcpy(priv->unifi_macaddress, ptr + 2, 6);
+ }
+ }
+ }
+ }
+ /* This is what we are expecting for, return success. */
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+} /* wait_for_event() */
+
+
+static int
+send_mlme_set_req(MANAGER_PRIV_DATA *priv, unsigned char *req_data, unsigned int req_len)
+{
+ unsigned char *sig_ptr;
+ CSR_SIGNAL *sig;
+ CSR_DATAREF *datarefptr;
+ int r = 0;
+ unsigned int signal_len = offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_REQUEST);
+
+ sig_ptr = malloc(signal_len + req_len);
+ if (sig_ptr == NULL) {
+ return ERROR_IO_ERROR;
+ }
+ memset(sig_ptr, 0, signal_len + req_len);
+ sig = (CSR_SIGNAL *)sig_ptr;
+
+ sig->SignalPrimitiveHeader.SignalId = CSR_MLME_SET_REQUEST_ID;
+ sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
+ sig->SignalPrimitiveHeader.SenderProcessId = 0xC013;
+ datarefptr = (CSR_DATAREF*)&sig->u;
+ datarefptr->DataLength = req_len;
+
+ memcpy(sig_ptr + signal_len, req_data, req_len);
+ signal_len += req_len;
+
+ /* Send the command to the unifi. */
+ if (write(priv->Fd, sig_ptr, signal_len) != signal_len) {
+ r = ERROR_IO_ERROR;
+ }
+
+ free(sig_ptr);
+ return r;
+} /* send_mlme_set_req() */
+
+static int
+send_mlme_get_req(MANAGER_PRIV_DATA *priv, unsigned char *req_data, unsigned int req_len)
+{
+ unsigned char *sig_ptr;
+ CSR_SIGNAL *sig;
+ CSR_DATAREF *datarefptr;
+ int r = 0;
+ unsigned int signal_len = offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_REQUEST);
+
+ sig_ptr = malloc(signal_len + req_len);
+ if (sig_ptr == NULL) {
+ return ERROR_IO_ERROR;
+ }
+ memset(sig_ptr, 0, signal_len + req_len);
+ sig = (CSR_SIGNAL *)sig_ptr;
+
+ sig->SignalPrimitiveHeader.SignalId = CSR_MLME_GET_REQUEST_ID;
+ sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
+ sig->SignalPrimitiveHeader.SenderProcessId = 0xC013;
+ datarefptr = (CSR_DATAREF*)&sig->u;
+ datarefptr->DataLength = req_len;
+
+ memcpy(sig_ptr + signal_len, req_data, req_len);
+ signal_len += req_len;
+
+ /* Send the command to the unifi. */
+ if (write(priv->Fd, sig_ptr, signal_len) != signal_len) {
+ r = ERROR_IO_ERROR;
+ }
+
+ free(sig_ptr);
+ return r;
+} /* send_mlme_get_req() */
+
+
+
+int
+drv_set_mac_address(MANAGER_PRIV_DATA *priv)
+{
+ unsigned char varbind[MAX_VARBIND_LENGTH];
+ unsigned char *ptr;
+ int len, r;
+ unsigned char invalid_macaddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ /* Build a varbind of OID and INTEGER */
+ varbind[0] = MIB_TAG_SEQUENCE;
+ ptr = varbind + 2; /* assumes length will always be one octet */
+
+ /* Build the MAC address MLME-GET.req */
+ len = MibEncodeOID(dot11MACAddress_oid, ptr);
+ len += MibEncodeNull(ptr+len);
+ varbind[1] = len;
+
+ /* Send the MLME-GET.req */
+ r = send_mlme_get_req(priv, varbind, len+2);
+ if (r != 0) {
+ return r;
+ }
+
+ /* Wait for the MLME-GET.cfm */
+ r = wait_for_event(priv, CSR_MLME_GET_CONFIRM_ID);
+ if (r != 0) {
+ return r;
+ }
+
+ /* If the MAC passed from the SME a new valid .. */
+ if ((memcmp(priv->macaddress, invalid_macaddr, 6) != 0) &&
+ (memcmp(priv->macaddress, priv->unifi_macaddress, 6) != 0)) {
+ /* .. update the existing address. */
+ len = 0;
+ /* Build the MAC address MLME-SET.req */
+ len = MibEncodeOID(dot11MACAddress_oid, ptr);
+ len += MibEncodeOctetString(priv->macaddress, 6, ptr+len);
+ varbind[1] = len;
+
+ /* Send the request. */
+ r = send_mlme_set_req(priv, varbind, len+2);
+ if (r != 0) {
+ return r;
+ }
+
+ /* Wait for MAC address confirm. */
+ r = wait_for_event(priv, CSR_MLME_SET_CONFIRM_ID);
+ if (r != 0) {
+ return r;
+ }
+ } else {
+ memcpy(priv->macaddress, priv->unifi_macaddress, 6);
+ }
+
+ return 0;
+} /* drv_set_mac_address() */
+
+
+int
+drv_set_reset_state(MANAGER_PRIV_DATA *priv)
+{
+ CSR_SIGNAL signal;
+ CSR_MLME_RESET_REQUEST *req;
+ int signal_len;
+
+ memset((void*)&signal, 0, sizeof(CSR_SIGNAL));
+
+ signal.SignalPrimitiveHeader.SignalId = CSR_MLME_RESET_REQUEST_ID;
+ signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
+ signal.SignalPrimitiveHeader.SenderProcessId = 0xC013;
+
+ /* Set up MLME-RESET request */
+ req = &signal.u.MlmeResetRequest;
+ memcpy(req->StaAddress.x, priv->macaddress, 6);
+ req->SetDefaultMib = 1;
+
+ signal_len = offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESET_REQUEST);
+
+ /* Send the command to the unifi. */
+ if (write(priv->Fd, (unsigned char *)&signal, signal_len) != signal_len) {
+ return ERROR_IO_ERROR;
+ }
+
+ return 0;
+} /* drv_set_reset_state() */
+
+
+static int
+_dl_mibs(MANAGER_PRIV_DATA *priv, unsigned char *mibdata, int miblen)
+{
+ unsigned char *header;
+ int version;
+ int filelen;
+ unsigned char *varbind;
+ int r;
+
+ /* Check mibdata contains at least the file header (10) and one MIB (2) */
+ if (miblen < 12) {
+ perror("Invalid MIB file");
+ return ERROR_IO_ERROR;
+ }
+
+ /*
+ * Read file header.
+ */
+ header = mibdata;
+ mibdata += 10;
+
+ if ((header[0] != 'U') || (header[1] != 'D') ||
+ (header[2] != 'M') || (header[3] != 'I'))
+ {
+ perror("Bad header in MIB file");
+ return ERROR_IO_ERROR;
+ }
+ version = header[4] + (header[5] << 8);
+ filelen = header[6] + (header[7] << 8) +
+ (header[8] << 16) + (header[9] << 24);
+
+ /* Check file length from file against given file size */
+ if ((filelen + 10) != miblen) {
+ perror("Length mismatch for MIB file.\n");
+
+ /* Truncate filelen if necessary */
+ if ((filelen + 10) > miblen) {
+ filelen = miblen - 10;
+ }
+ }
+
+ /*
+ * Read and set MIBs
+ */
+ while (filelen > 2)
+ {
+ int datalen;
+ unsigned char *vblen;
+
+ /* Read length field */
+ vblen = mibdata;
+ mibdata += 2;
+ filelen -= 2;
+
+ datalen = (vblen[1] << 8) + vblen[0];
+ if (datalen > filelen) {
+ perror("End of file reached reading MIB\n");
+ return ERROR_IO_ERROR;
+ }
+
+ /* Now read the varbind itself */
+ varbind = mibdata;
+ mibdata += datalen;
+ filelen -= datalen;
+
+ /* Check */
+ if ((varbind[1] + 2) != datalen) {
+ perror("Malformed MIB entry, bad length.\n");
+ return ERROR_IO_ERROR;
+ }
+
+ r = send_mlme_set_req(priv, varbind, varbind[1] + 2);
+ if (r < 0) {
+ /* Exit immediately */
+ return r;
+ }
+ r = wait_for_event(priv, CSR_MLME_SET_CONFIRM_ID);
+ if (r != 0) {
+ /* Exit immediately */
+ return r;
+ }
+ }
+
+ return 0;
+
+} /* _dl_mibs() */
+
+
+int
+drv_download_mib(MANAGER_PRIV_DATA *priv, char *mib_file)
+{
+ FILE *fp;
+ struct stat st;
+ int r;
+ unsigned char *img_data;
+ unsigned int img_len;
+
+ if (stat(mib_file, &st)) {
+ perror("Failed to stat img file");
+ return ERROR_IO_ERROR;
+ }
+
+ img_len = st.st_size;
+ fp = fopen(mib_file, "r");
+ if (!fp) {
+ perror("Failed to open firmware file");
+ return ERROR_IO_ERROR;
+ }
+ img_data = (unsigned char *)malloc(img_len);
+ if (img_data == NULL) {
+ perror("Failed to allocate memory for firmware");
+ fclose(fp);
+ return ERROR_IO_ERROR;
+ }
+ /* NB This assumes fread() will successfully read whole file in one call
+ */
+ if (fread(img_data, 1, img_len, fp) != img_len) {
+ perror("Failed to read MIB file");
+ free(img_data);
+ fclose(fp);
+ return ERROR_IO_ERROR;
+ }
+
+ fclose(fp);
+
+ r = _dl_mibs(priv, img_data, img_len);
+ if (r) {
+ perror("Failed to download UniFi MIBs");
+ }
+
+ free(img_data);
+ return r;
+} /* drv_download_mib() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.h
new file mode 100644
index 0000000..71a6eca
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/sme_drv.h
@@ -0,0 +1,80 @@
+/*
+ * ---------------------------------------------------------------------------
+ * FILE: sme_drv.h
+ *
+ * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ---------------------------------------------------------------------------
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#define UNION union
+#define STRUCT struct
+#define PACKING
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned long uint32;
+typedef unsigned long long uint64;
+typedef short int16;
+typedef long int32;
+typedef uint8 uint24[3];
+
+#include "driver/sigs.h"
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+
+#define MAX_GUID_LENGTH 32
+#define MAX_MIB_FILES 4
+#define MAX_MIB_PATH_LEN 128
+
+typedef struct MANAGER_PRIV_DATA {
+ int Fd;
+ int drv_connection;
+ int kill_event_thread;
+ int event_thread_running;
+ char guid[MAX_GUID_LENGTH];
+ unsigned char macaddress[6];
+ unsigned char unifi_macaddress[6];
+ unsigned int mib_files_num;
+ char mib_files[MAX_MIB_FILES][MAX_MIB_PATH_LEN];
+} MANAGER_PRIV_DATA;
+
+
+
+#define DD_IND_ERROR 0x01
+#define DD_IND_EXIT 0x02
+#define DD_COMM_ERROR 0x04
+#define DD_SME_NOT_PRESENT 0x10
+#define DD_SME_PRESENT 0x20
+
+#define ERROR_IO_ERROR -1
+
+#define INVALID_SIGNAL 0x0000
+
+int drv_set_mac_address(MANAGER_PRIV_DATA *priv);
+int drv_set_reset_state(MANAGER_PRIV_DATA *priv);
+int drv_download_mib(MANAGER_PRIV_DATA *priv, char *mib_file);
+
+int wait_for_event(MANAGER_PRIV_DATA *priv, int signal_id);
+
+
+int MibEncodeOID(const char *oid_str, unsigned char *buf);
+int MibEncodeOctetString(unsigned char *aStr, int aStrLength, unsigned char *aData);
+int MibEncodeNull(unsigned char *aData);
+int MibEncodeInteger(int aVal, unsigned char *aData);
+int MibEncodeBoolean(int aVal, unsigned char *aData);
+
+int MibDecodeInteger(unsigned char *aData, int *aVal);
+int MibDecodeOctetString(unsigned char *aData, int aStrLength, unsigned char *aStr);
+int MibDecodeBoolean(unsigned char *aData, uint32 *aVal);
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config.c
new file mode 100644
index 0000000..5e24b3e
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config.c
@@ -0,0 +1,682 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_config.c
+ *
+ * Get/Set configuration to the UniFi driver.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <stddef.h>
+
+#include "osa_types.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "unifiio.h"
+
+#include "unifi_config_lib.h"
+
+
+static const char*
+trace_traffic_type(unifi_traffic_type traffic)
+{
+ switch (traffic)
+ {
+ case unifi_traffic_occasional:
+ return "Occasional";
+ case unifi_traffic_bursty:
+ return "Bursty";
+ case unifi_traffic_periodic:
+ return "Periodic";
+ case unifi_traffic_continuous:
+ return "Continuous";
+ default:
+ return "ERROR: unrecognised Traffic Type";
+ }
+ }
+
+
+static const char*
+trace_power_save_type(unifi_PowerSaveLevel power_save)
+{
+ switch (power_save)
+ {
+ case unifi_PowerSaveLow:
+ return "Active";
+ case unifi_PowerSaveHigh:
+ return "Full";
+ case unifi_PowerSaveMed:
+ return "Fast";
+ case unifi_PowerSaveAuto:
+ return "Auto";
+ default:
+ return "ERROR: unrecognised Power Save Mode";
+ }
+ }
+
+
+static const char*
+trace_coex_scheme_type(unifi_CoexScheme coex_scheme)
+{
+ switch (coex_scheme)
+ {
+ case unifi_CoexSchemeDisabled:
+ return "None";
+ case unifi_CoexSchemeCsr:
+ return "CSR";
+ case unifi_CoexSchemeCsrChannel:
+ return "CSR Channel";
+ case unifi_CoexSchemePTA:
+ return "PTA";
+ default:
+ return "ERROR: unrecognised Coex Scheme";
+ }
+ }
+
+
+static const char*
+trace_power_supply_type(unifi_HostPowerMode power_supply)
+{
+ switch (power_supply)
+ {
+ case unifi_HostActive:
+ return "Running on mains";
+ case unifi_HostPowersave:
+ return "Running on batteries";
+ case unifi_HostFullPowersave:
+ return "Unspecified power supply";
+ default:
+ return "ERROR: unrecognised power supply";
+ }
+ }
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_byte
+ * is_delim
+ *
+ * Support fns.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+read_byte(char *p, unsigned char *b)
+{
+ int n = 0;
+ int i, c, v;
+
+ /* Use a loop so we accept single digit fields */
+ v = 0;
+ for (i = 0; i < 2; i++) {
+
+ c = *p++;
+
+ if ((c >= '0') && (c <= '9')) {
+ c -= '0';
+ } else if ((c >= 'A') && (c <= 'F')) {
+ c = c - 'A' + 10;
+ } else if ((c >= 'a') && (c <= 'f')) {
+ c = c - 'a' + 10;
+ } else {
+ break;
+ }
+
+ v = (v * 16) + c;
+ n++;
+ }
+
+ if (n) {
+ *b = v;
+ }
+
+ return n;
+} /* read_byte() */
+
+
+static int
+is_delim(int ch)
+{
+ return ((ch == ':') || (ch == '.') || (ch == ','));
+} /* is_delim() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_ie
+ *
+ *
+ * Arguments:
+ * arg The command-line argument string
+ * periodic_ie Pointer to the array to receive IE.
+ *
+ * Returns:
+ * number of bytes on success, -1 if the string does not conform to expected format.
+ * ---------------------------------------------------------------------------
+ */
+static int
+read_ie(char *arg, unsigned char *periodic_ie)
+{
+ char *p = arg;
+ int i, n, offset;
+
+ i = 0;
+ n = 0;
+ offset = 0;
+ do {
+ n = read_byte(p, &periodic_ie[offset]);
+ p += n;
+
+ if (!is_delim(*p)) break;
+
+ p++;
+ offset ++;
+ } while ((n > 0) && (n < UNIFI_CFG_MAX_ADDTS_IE_LENGTH));
+
+ return offset+1;
+} /* read_ie() */
+
+
+int
+main(int argc, char **argv)
+{
+ char device[32];
+ int start;
+ int index;
+ int r = 0;
+ int fd;
+ unifi_cfg_power_t wifi_power = UNIFI_CFG_POWER_UNSPECIFIED;
+ unifi_cfg_powersave_t wifi_powersave = UNIFI_CFG_POWERSAVE_UNSPECIFIED;
+ unifi_cfg_powersupply_t wifi_powersupply = UNIFI_CFG_POWERSUPPLY_UNSPECIFIED;
+ unsigned char wifi_filter_set;
+ unsigned int wifi_filter;
+ unsigned char uapsd_mask_set;
+ uint8 uapsd_mask;
+ unsigned char maxsp_set;
+ uint8 maxsp_length;
+ uint8 wmm_qos_info;
+ unsigned char wmm_addts_tid_set;
+ uint32 wmm_addts_tid;
+ unsigned char wmm_delts_tid_set;
+ uint32 wmm_delts_tid;
+ unsigned char wmm_addts_ie_set;
+ unsigned char addts_ie_length;
+ uint8 addts_ie[UNIFI_CFG_MAX_ADDTS_IE_LENGTH];
+ unsigned char show_set;
+ int option_index = 0, optc;
+ char *value;
+ unsigned char uchar_value;
+
+ static const struct option long_options[] = {
+ {"dev", 1, 0, 0},
+ {"show", 0, 0, 0},
+ {"wifion", 0, 0, 0},
+ {"wifioff", 0, 0, 0},
+ {"powersave", 1, 0, 0},
+ {"batteries", 1, 0, 0},
+ {"filter", 1, 0, 0},
+ {"uapsd", 1, 0, 0},
+ {"maxsp", 1, 0, 0},
+ {"addts_ie", 1, 0, 0},
+ {"addts_tid", 1, 0, 0},
+ {"delts_tid", 1, 0, 0},
+ {0, 0, 0, 0} };
+
+ static const char *filter_options[] = {"dhcp", "arp", "nbns", "nbds",
+ "cups", "none", "all", NULL };
+
+ static const char *uapsd_options[] = {"be", "bk", "vi", "vo", "none",
+ "all", "default", NULL };
+
+ static const char *maxsp_options[] = {"2", "4", "6", "all", NULL };
+
+ if (argc > 1) {
+ if (!strcasecmp(argv[1], "--help")) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " unifi_config --dev /dev/unifiudiN \n");
+ fprintf(stderr, " [ --show ] \n");
+ fprintf(stderr, " [ --wifioff ] \n");
+ fprintf(stderr, " [ --wifion ] \n");
+ fprintf(stderr, " [ --batteries {yes | no} ] \n");
+ fprintf(stderr, " [ --powersave {none | fast | full | auto} ] \n");
+ fprintf(stderr, " [ --filter {dhcp,arp,nbns,nbds,cups | none | all} ] \n");
+ fprintf(stderr, " [ --uapsd {be,bk,vi,vo | none | all} ] \n");
+ fprintf(stderr, " [ --maxsp {2,4,6 | all} ] \n");
+ fprintf(stderr, " [ --addts_ie {NN:NN:...:NN (in hex)} ] \n");
+ fprintf(stderr, " [ --addts_tid {NN (in hex)} ] \n");
+ fprintf(stderr, " [ --delts_tid {NN (in hex)} ] \n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Note that a valid ADDTS command must specify both --addts_ie and --addts_tid\n");
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ }
+
+ start = 0;
+ show_set = 0;
+ wifi_filter_set = 0;
+ wifi_filter = UNIFI_CFG_FILTER_NONE;
+ uapsd_mask_set = uapsd_mask = 0;
+ maxsp_set = maxsp_length = wmm_qos_info = 0;
+ wmm_addts_tid_set = addts_ie_length = wmm_addts_ie_set = wmm_addts_tid = 0;
+ wmm_delts_tid_set = wmm_delts_tid = 0;
+
+ while ((optc = getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
+ start = 1;
+ if (optc == 0) {
+
+ if (!strcasecmp(long_options[option_index].name, "dev")) {
+ r = strlen(optarg);
+ if (r >= (sizeof(device) - 1)) {
+ printf("dev arg %s is too long\n", optarg);
+ exit(1);
+ }
+ memcpy(device, optarg, r);
+ device[r] = 0;
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "wifion")) {
+ wifi_power = UNIFI_CFG_POWER_ON;
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "wifioff")) {
+ wifi_power = UNIFI_CFG_POWER_OFF;
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "show")) {
+ show_set = 1;
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "batteries")) {
+
+ if (optarg == NULL) {
+ printf("option batteries requires an argument\n");
+ exit(1);
+ }
+
+ if (!strcasecmp(optarg, "yes")) {
+ wifi_powersupply = UNIFI_CFG_POWERSUPPLY_BATTERIES;
+ } else if (!strcasecmp(optarg, "no")) {
+ wifi_powersupply = UNIFI_CFG_POWERSUPPLY_MAINS;
+ } else {
+ printf("batteries invalid option: %s\n", optarg);
+ start = 0;
+ }
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "powersave")) {
+
+ if (optarg == NULL) {
+ printf("option powersave requires an argument\n");
+ exit(1);
+ }
+
+ if (!strcasecmp(optarg, "none")) {
+ wifi_powersave = UNIFI_CFG_POWERSAVE_NONE;
+ } else if (!strcasecmp(optarg, "fast")) {
+ wifi_powersave = UNIFI_CFG_POWERSAVE_FAST;
+ } else if (!strcasecmp(optarg, "full")) {
+ wifi_powersave = UNIFI_CFG_POWERSAVE_FULL;
+ } else if (!strcasecmp(optarg, "auto")) {
+ wifi_powersave = UNIFI_CFG_POWERSAVE_AUTO;
+ } else {
+ printf("powersave invalid option: %s\n", optarg);
+ start = 0;
+ }
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "filter")) {
+
+ while ((index = getsubopt(&optarg, filter_options, &value)) != -1) {
+ switch(index) {
+ case 0:
+ wifi_filter |= UNIFI_CFG_FILTER_DHCP;
+ wifi_filter_set = 1;
+ break;
+ case 1:
+ wifi_filter |= UNIFI_CFG_FILTER_ARP;
+ wifi_filter_set = 1;
+ break;
+ case 2:
+ wifi_filter |= UNIFI_CFG_FILTER_NBNS;
+ wifi_filter_set = 1;
+ break;
+ case 3:
+ wifi_filter |= UNIFI_CFG_FILTER_NBDS;
+ wifi_filter_set = 1;
+ break;
+ case 4:
+ wifi_filter |= UNIFI_CFG_FILTER_CUPS;
+ wifi_filter_set = 1;
+ break;
+ case 5:
+ wifi_filter = UNIFI_CFG_FILTER_NONE;
+ wifi_filter_set = 1;
+ break;
+ case 6:
+ wifi_filter = UNIFI_CFG_FILTER_ALL;
+ wifi_filter_set = 1;
+ break;
+ default:
+ printf("unrecognised filter arg: %s\n", filter_options[index]);
+ break;
+ }
+ }
+
+ if (!wifi_filter_set)
+ {
+ printf("option --filter requires an argument\n");
+ exit(1);
+ }
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "uapsd")) {
+
+ while ((index = getsubopt(&optarg, uapsd_options, &value)) != -1) {
+ switch(index) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ uapsd_mask |= (1 << index);
+ uapsd_mask_set = 1;
+ break;
+ case 4:
+ uapsd_mask = 0x00;
+ uapsd_mask_set = 1;
+ break;
+ case 5:
+ uapsd_mask = 0x0F; /* All 4 bits set to 1 */
+ uapsd_mask_set = 1;
+ break;
+ case 6:
+ uapsd_mask = 0xFF; /* SME will handle this */
+ uapsd_mask_set = 1;
+ break;
+ default:
+ printf("unrecognised filter arg: %s\n", uapsd_options[index]);
+ break;
+ }
+ }
+
+ if (!uapsd_mask_set)
+ {
+ printf("option --uapsd requires an argument\n");
+ exit(1);
+ }
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "maxsp")) {
+
+ while ((index = getsubopt(&optarg, maxsp_options, &value)) != -1) {
+ switch(index) {
+ case 0:
+ maxsp_length = 0x01;
+ maxsp_set = 1;
+ break;
+ case 1:
+ maxsp_length = 0x02;
+ maxsp_set = 1;
+ break;
+ case 2:
+ maxsp_length = 0x03;
+ maxsp_set = 1;
+ break;
+ case 3:
+ maxsp_length = 0x00;
+ maxsp_set = 1;
+ break;
+ default:
+ printf("unrecognised filter arg: %s\n", maxsp_options[index]);
+ break;
+ }
+ }
+
+ if (!maxsp_set)
+ {
+ printf("option --maxsp requires an argument\n");
+ exit(1);
+ }
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "addts_ie")) {
+ addts_ie_length = read_ie(optarg, addts_ie);
+ if (addts_ie_length != UNIFI_CFG_MAX_ADDTS_IE_LENGTH) {
+ printf("option --addts_ie requires a valid %d bytes hex array\n",
+ UNIFI_CFG_MAX_ADDTS_IE_LENGTH);
+ exit(1);
+ }
+ wmm_addts_ie_set = 1;
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "addts_tid")) {
+ if (!read_byte(optarg, &uchar_value)) {
+ printf("option --addts_tid requires a valid hex number\n");
+ exit(1);
+ }
+ wmm_addts_tid = uchar_value;
+ wmm_addts_tid_set = 1;
+ continue;
+ }
+
+ if (!strcasecmp(long_options[option_index].name, "delts_tid")) {
+ if (!read_byte(optarg, &uchar_value)) {
+ printf("option --addts_tid requires a valid hex number\n");
+ exit(1);
+ }
+ wmm_delts_tid = uchar_value;
+ wmm_delts_tid_set = 1;
+ continue;
+ }
+
+ printf("Unrecognised option: %s\n", long_options[option_index].name);
+ start = 0;
+ break;
+
+ } else {
+ start = 0;
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf("Unrecognised option(s) ignored: ");
+ while (optind < argc) {
+ printf ("%s ", argv[optind++]);
+ }
+ printf ("\n");
+ }
+
+ if (start == 0) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " unifi_config --dev /dev/unifiudiN \n");
+ fprintf(stderr, " [ --show ] \n");
+ fprintf(stderr, " [ --wifioff ] \n");
+ fprintf(stderr, " [ --wifion ] \n");
+ fprintf(stderr, " [ --batteries {yes | no} ] \n");
+ fprintf(stderr, " [ --powersave {none | fast | full | auto} ] \n");
+ fprintf(stderr, " [ --filter {dhcp,arp,nbns,nbds,cups | none | all} ] \n");
+ fprintf(stderr, " [ --uapsd {be,bk,vi,vo | none | all} ] \n");
+ fprintf(stderr, " [ --maxsp {2,4,6 | all} ] \n");
+ fprintf(stderr, " [ --addts_ie {NN:NN:...:NN (in hex)} ] \n");
+ fprintf(stderr, " [ --addts_tid {NN (in hex)} ] \n");
+ fprintf(stderr, " [ --delts_tid {NN (in hex)} ] \n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Note that a valid ADDTS command must specify both --addts_ie and --addts_tid\n");
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+
+#if 0
+ fprintf(stderr, " Using:\n");
+ fprintf(stderr, " DEVICE: %s\n", device);
+ fprintf(stderr, " Show: %s\n", (show_set) ? "YES" : "NO");
+ fprintf(stderr, " WiFi ON/OFF: %d\n", wifi_power);
+ fprintf(stderr, " Power: %d\n", wifi_powersave);
+ fprintf(stderr, " Filter: 0x%x\n", wifi_filter);
+ fprintf(stderr, " U-APSD Mask: 0x%x\n", uapsd_mask);
+ fprintf(stderr, "\n");
+#endif
+
+ fd = unifi_cfg_init(device);
+ if (fd < 0) {
+ perror("Failed to open device");
+ exit(errno);
+ }
+
+ if (wifi_power != UNIFI_CFG_POWER_UNSPECIFIED) {
+ r = unifi_cfg_set_power(fd, wifi_power);
+ if (r < 0) {
+ printf("UNIFI_CFG_POWER: failed\n");
+ goto EXIT;
+ }
+ }
+
+ if (wifi_powersave != UNIFI_CFG_POWERSAVE_UNSPECIFIED) {
+ r = unifi_cfg_set_power_save(fd, wifi_powersave);
+ if (r < 0) {
+ printf("UNIFI_CFG_POWERSAVE: failed\n");
+ goto EXIT;
+ }
+ }
+
+ if (wifi_powersupply != UNIFI_CFG_POWERSUPPLY_UNSPECIFIED) {
+ r = unifi_cfg_set_power_supply(fd, wifi_powersupply);
+ if (r < 0) {
+ printf("UNIFI_CFG_POWERSUPPLY: failed\n");
+ goto EXIT;
+ }
+ }
+
+ if (wifi_filter_set) {
+ r = unifi_cfg_set_filters(fd, wifi_filter);
+ if (r < 0) {
+ printf("UNIFI_CFG_FILTER: failed\n");
+ goto EXIT;
+ }
+ }
+
+ if (maxsp_set || uapsd_mask_set) {
+ /* Max SP Length can only be used with one or more U-APSD ACs */
+ if (!uapsd_mask && maxsp_set) {
+ printf("UNIFI_CFG_WMM_QOSINFO: Max SP Length can only be used with one or more U-APSD ACs\n");
+ goto EXIT;
+ }
+
+ wmm_qos_info = (maxsp_length << 5) | uapsd_mask;
+ r = unifi_cfg_set_wmm_qos_info(fd, wmm_qos_info);
+ if (r < 0) {
+ printf("UNIFI_CFG_WMM_QOSINFO: failed\n");
+ goto EXIT;
+ }
+ }
+
+ if (wmm_delts_tid_set) {
+ r = unifi_cfg_wmm_delts(fd, wmm_delts_tid);
+ if (r < 0) {
+ printf("UNIFI_CFG_WMM_DELTS: failed\n");
+ goto EXIT;
+ }
+ }
+
+ if (wmm_addts_tid_set && wmm_addts_ie_set) {
+ r = unifi_cfg_wmm_addts(fd, wmm_addts_tid, addts_ie, addts_ie_length);
+ if (r < 0) {
+ printf("UNIFI_CFG_WMM_ADDTS: failed\n");
+ goto EXIT;
+ }
+ }
+
+ if (show_set) {
+ unsigned char *result;
+ unifi_CoexInfo coex_info;
+ unifi_PowerSaveLevel power_save_info;
+ unifi_HostPowerMode host_power_mode;
+
+ result = (unsigned char*) (&coex_info);
+ r = unifi_cfg_get_info(fd, UNIFI_CFG_GET_COEX, result);
+ if (r < 0) {
+ printf("UNIFI_CFG_GET_COEX: failed\n");
+ goto EXIT;
+ }
+
+ printf("Current Coex Info:\n");
+ printf(" Traffic Type = %s\n",
+ trace_traffic_type(coex_info.currentTrafficType));
+ if (coex_info.currentTrafficType == unifi_traffic_periodic) {
+ printf(" Traffic Period = %d\n", coex_info.currentPeriod);
+ } else if (coex_info.currentCoexLatency) {
+ printf(" Traffic Latency = %d\n", coex_info.currentCoexLatency);
+ }
+ printf(" Power Save Mode = %s\n",
+ trace_power_save_type(coex_info.currentPowerSave));
+ printf(" Has Traffic Data = %s\n",
+ coex_info.hasTrafficData ? "Yes" : "No");
+ printf(" Has Bluetooth device = %s\n",
+ coex_info.hasBtDevice ? "Yes" : "No");
+ printf(" Coex Scheme = %s\n",
+ trace_coex_scheme_type(coex_info.currentCoexScheme));
+
+ result = (unsigned char*) (&power_save_info);
+ r = unifi_cfg_get_info(fd, UNIFI_CFG_GET_POWER_MODE, result);
+ if (r < 0) {
+ printf("UNIFI_CFG_GET_POWER_MODE: failed\n");
+ goto EXIT;
+ }
+
+ printf("Configured Power Save Mode = %s\n",
+ trace_power_save_type(power_save_info));
+
+ result = (unsigned char*) (&host_power_mode);
+ r = unifi_cfg_get_info(fd, UNIFI_CFG_GET_POWER_SUPPLY, result);
+ if (r < 0) {
+ printf("UNIFI_CFG_GET_POWER_SUPPLY: failed\n");
+ goto EXIT;
+ }
+
+ printf("%s\n",
+ trace_power_supply_type(host_power_mode));
+
+ }
+
+
+EXIT:
+ /* Kill communication with driver. */
+ unifi_cfg_deinit(fd);
+
+ return r;
+} /* main() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.c
new file mode 100644
index 0000000..2179683
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.c
@@ -0,0 +1,336 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_config_lib.c
+ *
+ * Get/Set configuration to the UniFi driver library.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <stddef.h>
+
+#include "osa_types.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "unifiio.h"
+#include "unifi_config_lib.h"
+
+#if 0
+static void
+dump(unsigned char* in_buffer, unsigned int count)
+{
+ unsigned int i;
+ for (i=0; i<count; i++) {
+ printf("%02X ", in_buffer[i]);
+ if ((i % 16) == 15) {
+ printf("\n");
+ }
+ }
+ printf("\n");
+}
+#endif
+
+static void TcpIp4Tclas(tclas_t* tclas)
+{
+ memset(tclas, 0, sizeof(tclas_t));
+ tclas->element_id = 14;
+ tclas->length = sizeof(tcpip_clsfr_t) + 1;
+ tclas->user_priority = 0;
+ tclas->tcp_ip_cls_fr.cls_fr_type = 1;
+ tclas->tcp_ip_cls_fr.version = 4;
+}
+
+static uint32
+FilterCups(tclas_t* tclas)
+{
+ TcpIp4Tclas(tclas);
+ ((uint8*)(&tclas->tcp_ip_cls_fr.source_port))[0] = 0x02;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.source_port))[1] = 0x77;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.dest_port))[0] = 0x02;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.dest_port))[1] = 0x77;
+ tclas->tcp_ip_cls_fr.protocol = 0x11;
+ tclas->tcp_ip_cls_fr.cls_fr_mask = 0x58; //bits: 3,4,6
+ return sizeof(tclas_t);
+}
+
+static uint32
+FilterNbns(tclas_t* tclas)
+{
+ TcpIp4Tclas(tclas);
+ ((uint8*)(&tclas->tcp_ip_cls_fr.source_port))[0] = 0x00;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.source_port))[1] = 0x89;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.dest_port))[0] = 0x00;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.dest_port))[1] = 0x89;
+ tclas->tcp_ip_cls_fr.protocol = 0x11;
+ tclas->tcp_ip_cls_fr.cls_fr_mask = 0x58; //bits: 3,4,6
+
+ return sizeof(tclas_t);
+}
+
+static uint32
+FilterNbds(tclas_t* tclas)
+{
+ TcpIp4Tclas(tclas);
+ ((uint8*)(&tclas->tcp_ip_cls_fr.source_port))[0] = 0x00;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.source_port))[1] = 0x8A;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.dest_port))[0] = 0x00;
+ ((uint8*)(&tclas->tcp_ip_cls_fr.dest_port))[1] = 0x8A;
+ tclas->tcp_ip_cls_fr.protocol = 0x11;
+ tclas->tcp_ip_cls_fr.cls_fr_mask = 0x58; //bits: 3,4,6
+ return sizeof(tclas_t);
+}
+
+static int
+_add_filter(unsigned char* in_buffer, unsigned int filter)
+{
+ uf_cfg_bcast_packet_filter_t *bcast_packet_filter;
+ unsigned char *tclas;
+ unsigned int bcast_packet_filter_size;
+ unsigned int tclas_ies_length;
+ uint32 added_tclas_length;
+
+ bcast_packet_filter = (uf_cfg_bcast_packet_filter_t*)in_buffer;
+
+ bcast_packet_filter->filter_mode = 0;
+ tclas = bcast_packet_filter->tclas_ies;
+ bcast_packet_filter_size = sizeof(uf_cfg_bcast_packet_filter_t);
+ tclas_ies_length = 0;
+
+ bcast_packet_filter->arp_filter = filter & UNIFI_CFG_FILTER_ARP;
+ bcast_packet_filter->dhcp_filter = filter & UNIFI_CFG_FILTER_DHCP;
+
+ if(filter & UNIFI_CFG_FILTER_CUPS) {
+ added_tclas_length = FilterCups((tclas_t*)(tclas + tclas_ies_length));
+ tclas_ies_length += added_tclas_length;
+ bcast_packet_filter_size += added_tclas_length;
+ }
+
+ if(filter & UNIFI_CFG_FILTER_NBNS) {
+ added_tclas_length = FilterNbns((tclas_t*)(tclas + tclas_ies_length));
+ tclas_ies_length += added_tclas_length;
+ bcast_packet_filter_size += added_tclas_length;
+ }
+
+ if(filter & UNIFI_CFG_FILTER_NBDS) {
+ added_tclas_length = FilterNbds((tclas_t*)(tclas + tclas_ies_length));
+ tclas_ies_length += added_tclas_length;
+ bcast_packet_filter_size += added_tclas_length;
+ }
+
+ bcast_packet_filter->tclas_ies_length = tclas_ies_length;
+
+ /*
+ dump(bcast_packet_filter, sizeof(uf_cfg_bcast_packet_filter_t));
+ dump(tclas, bcast_packet_filter->tclas_ies_length);
+ */
+
+ return (tclas_ies_length) ? (bcast_packet_filter_size - 1) : bcast_packet_filter_size;
+}
+
+
+int unifi_cfg_init(char *device)
+{
+ int fd;
+
+ /* Start communication with driver. */
+ fd = open(device, O_RDWR);
+ if (fd < 0) {
+ printf("Failed to open device\n");
+ }
+ return fd;
+}
+
+int unifi_cfg_deinit(int fd)
+{
+ /* Kill communication with driver. */
+ close(fd);
+
+ return 0;
+}
+
+int unifi_cfg_set_filters(int fd, unsigned int filter_type)
+{
+ int r, filter_size;
+ unsigned char buffer[128];
+
+ *((unifi_cfg_command_t*)buffer) = UNIFI_CFG_FILTER;
+
+ filter_size = _add_filter(buffer + sizeof(unsigned int) + sizeof(unifi_cfg_command_t),
+ filter_type);
+ *((unsigned int*)(buffer + sizeof(unifi_cfg_command_t))) = filter_size;
+
+ r = ioctl(fd, UNIFI_CFG, buffer);
+ if (r < 0) {
+ printf("UNIFI_CFG: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_cfg_set_wmm_qos_info(int fd, uint8 wmm_qos_info)
+{
+ int r;
+ unsigned char buffer[8];
+
+ *((unifi_cfg_command_t*)buffer) = UNIFI_CFG_WMM_QOSINFO;
+ *((uint8*)(buffer + sizeof(unifi_cfg_command_t))) = wmm_qos_info;
+
+ r = ioctl(fd, UNIFI_CFG, buffer);
+ if (r < 0) {
+ printf("unifi_cfg_set_wmm_qos_info: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_cfg_set_power_save(int fd, unifi_cfg_powersave_t power_mode)
+{
+ int r;
+ unsigned char buffer[16];
+
+ *((unifi_cfg_command_t*)buffer) = UNIFI_CFG_POWERSAVE;
+ *((unifi_cfg_powersave_t*)(buffer + sizeof(unifi_cfg_command_t))) = power_mode;
+
+ r = ioctl(fd, UNIFI_CFG, buffer);
+ if (r < 0) {
+ printf("unifi_cfg_set_power_save: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+int unifi_cfg_set_power(int fd, unifi_cfg_power_t power)
+{
+ int r;
+ unsigned char buffer[16];
+
+ *((unifi_cfg_command_t*)buffer) = UNIFI_CFG_POWER;
+ *((unifi_cfg_power_t*)(buffer + sizeof(unifi_cfg_command_t))) = power;
+
+ r = ioctl(fd, UNIFI_CFG, buffer);
+ if (r < 0) {
+ printf("unifi_cfg_set_power: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+int unifi_cfg_set_power_supply(int fd, unifi_cfg_powersupply_t power_supply)
+{
+ int r;
+ unsigned char buffer[16];
+
+ *((unifi_cfg_command_t*)buffer) = UNIFI_CFG_POWERSUPPLY;
+ *((unifi_cfg_powersupply_t*)(buffer + sizeof(unifi_cfg_command_t))) = power_supply;
+
+ r = ioctl(fd, UNIFI_CFG, buffer);
+ if (r < 0) {
+ printf("unifi_cfg_set_power_supply: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_cfg_wmm_addts(int fd, uint32 addts_tid,
+ uint8 *addts_ie, uint8 addts_ie_length)
+{
+ int r;
+ static unsigned char buffer[UNIFI_CFG_MAX_ADDTS_IE_LENGTH + 16];
+ uint8 *buf_pos;
+
+ if (addts_ie_length > UNIFI_CFG_MAX_ADDTS_IE_LENGTH) {
+ printf("unifi_cfg_wmm_addts: IE exceeds UNIFI_CFG_MAX_ADDTS_IE_LENGTH\n");
+ return -EINVAL;
+ }
+
+ buf_pos = buffer;
+ *((unifi_cfg_command_t*)buf_pos) = UNIFI_CFG_WMM_ADDTS;
+
+ buf_pos += sizeof(unifi_cfg_command_t);
+ *((uint32*)buf_pos) = addts_tid;
+
+ buf_pos += sizeof(uint32);
+ *((uint8*)buf_pos) = addts_ie_length;
+
+ buf_pos += sizeof(uint8);
+ memcpy(buf_pos, addts_ie, addts_ie_length);
+
+ r = ioctl(fd, UNIFI_CFG, buffer);
+ if (r < 0) {
+ printf("unifi_cfg_wmm_addts: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_cfg_wmm_delts(int fd, uint32 delts_tid)
+{
+ int r;
+ static unsigned char buffer[8];
+ uint8 *buf_pos;
+
+ buf_pos = buffer;
+ *((unifi_cfg_command_t*)buf_pos) = UNIFI_CFG_WMM_DELTS;
+
+ buf_pos += sizeof(unifi_cfg_command_t);
+ *((uint32*)buf_pos) = delts_tid;
+
+ r = ioctl(fd, UNIFI_CFG, buffer);
+ if (r < 0) {
+ printf("unifi_cfg_wmm_delts: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_cfg_get_info(int fd, unifi_cfg_get_t type,
+ unsigned char *out_buffer)
+{
+ int r;
+
+ if (out_buffer == NULL) {
+ return -1;
+ }
+
+ *((unifi_cfg_command_t*)out_buffer) = UNIFI_CFG_GET;
+ *((unifi_cfg_get_t*)(out_buffer + sizeof(unifi_cfg_command_t))) = type;
+
+ r = ioctl(fd, UNIFI_CFG, out_buffer);
+ if (r < 0) {
+ printf("unifi_cfg_set_power: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.h
new file mode 100644
index 0000000..2716e5d
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_config_lib.h
@@ -0,0 +1,35 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_config_lib.h
+ *
+ * Get/Set configuration to the UniFi driver library.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#ifndef UNIFI_CONFIG_LIB_H
+#define UNIFI_CONFIG_LIB_H
+
+
+int unifi_cfg_init(char *device);
+int unifi_cfg_deinit(int fd);
+int unifi_cfg_set_filters(int fd, unsigned int filter_type);
+int unifi_cfg_set_wmm_qos_info(int fd, uint8 wmm_qos_info);
+int unifi_cfg_wmm_addts(int fd, uint32 addts_tid,
+ uint8 *addts_ie, uint8 addts_ie_length);
+int unifi_cfg_wmm_delts(int fd, uint32 delts_tid);
+int unifi_cfg_set_power_save(int fd, unifi_cfg_powersave_t power_mode);
+int unifi_cfg_set_power_supply(int fd, unifi_cfg_powersupply_t power_supply);
+int unifi_cfg_set_power(int fd, unifi_cfg_power_t power);
+int unifi_cfg_get_info(int fd, unifi_cfg_get_t type,
+ unsigned char *out_buffer);
+
+#define UNIFI_CFG_MAX_ADDTS_IE_LENGTH 63
+
+#endif /* UNIFI_CONFIG_LIB_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_manager.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_manager.c
new file mode 100644
index 0000000..bd170e4
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_manager.c
@@ -0,0 +1,340 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_manager.c
+ *
+ * Download the loader and firmware to the UniFi.
+ * Set the MIB data files to the UniFi.
+ * Initialise the UniFi firmware (set MAC address, send MLME-RESET.req).
+ * Handle UniFi core driver errors, if SME is not present.
+ *
+ * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include "sme_drv.h"
+#include "driver/sigs.h"
+#include "unifiio.h"
+
+#ifndef isdigit
+#define isdigit(_c) (((_c) >= '0') && ((_c) <= '9'))
+#endif
+
+#define UNIFI_INIT_COMPLETED 0x02
+
+#define MAX_INIT_RETRIES 3
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_byte
+ * is_delim
+ *
+ * Support fns for read_mac() below.
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static int
+read_byte(const char *p, unsigned char *b)
+{
+ int n = 0;
+ int i, c, v;
+
+ /* Use a loop so we accept single digit fields */
+ v = 0;
+ for (i = 0; i < 2; i++) {
+
+ c = *p++;
+
+ if ((c >= '0') && (c <= '9')) {
+ c -= '0';
+ } else if ((c >= 'A') && (c <= 'F')) {
+ c = c - 'A' + 10;
+ } else if ((c >= 'a') && (c <= 'f')) {
+ c = c - 'a' + 10;
+ } else {
+ break;
+ }
+
+ v = (v * 16) + c;
+ n++;
+ }
+
+ if (n) {
+ *b = v;
+ }
+
+ return n;
+} /* read_byte() */
+
+
+static int
+is_delim(int ch)
+{
+ return ((ch == ':') || (ch == '.') || (ch == ','));
+} /* is_delim() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * read_mac
+ *
+ * Extract the MAC address from command line argument.
+ * The expected format is something like 00:00:5B:00:23:45, although
+ * '-' and ',' are also accepted as delimiters.
+ *
+ * Arguments:
+ * arg The command-line argument string
+ * macaddr Pointer to 6-byte array to receive decoded MAC address
+ *
+ * Returns:
+ * 0 on success, -1 if the string does not conform to expected format.
+ * ---------------------------------------------------------------------------
+ */
+static int
+read_mac(const char *arg, unsigned char *macaddr)
+{
+ const char *p = arg;
+ int i, n, j;
+
+ i = 0;
+
+ for (j=0;; j++) {
+ n = read_byte(p, &macaddr[j]);
+ if (n == 0)
+ return -1;
+ p += n;
+
+ if (j >= 5) {
+ return (*p != '\0') ? -1 : 0;
+ }
+
+ if (!is_delim(*p))
+ return -1;
+ p++;
+ }
+} /* read_mac() */
+
+
+int
+main(int argc, char *argv[])
+{
+ char *device = "/dev/unifi0";
+ char *initprog = NULL;
+ int start = 0;
+ int c, err;
+ int i, r;
+ int sme_is_present;
+
+ char *full_init = "1";
+
+ MANAGER_PRIV_DATA unifi_manager;
+
+ err = 0;
+ while ((c=getopt(argc, argv, "d:qs:b:x:")) != -1)
+ {
+ switch (c) {
+ case 's':
+ start = 1;
+ if (read_mac(optarg, unifi_manager.macaddress)) {
+ fprintf(stderr, "Badly formatted MAC address\n");
+ err++;
+ }
+ break;
+ case 'd':
+ device = optarg;
+ break;
+ case 'b':
+ full_init = optarg;
+ break;
+ case 'x':
+ initprog = optarg;
+ break;
+ default:
+ fprintf(stderr, "Bad option: %c\n", c);
+ err++;
+ }
+ }
+ if ((start == 0) && (optind >= argc)) {
+ fprintf(stderr, " No MIB file or MAC address given\n");
+ err++;
+ }
+ if (err) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " unifi_manager [-d dev] [-i chip] [-b init] -s mac mibfile mibfile...\n");
+ fprintf(stderr, " Set the MIB values in the given binary file (usually supplied\n");
+ fprintf(stderr, " with the chip).\n");
+ fprintf(stderr, " Specify '-' to read from stdin.\n");
+ fprintf(stderr, " Options:\n");
+ fprintf(stderr, " -d dev Use <dev> as the device (default is /dev/unifi0).\n");
+ fprintf(stderr, " -b init Fully initialise UniFi (0=No, 1=Yes).\n");
+ fprintf(stderr, " -s macaddr Set the card MAC address and start the network\n");
+ fprintf(stderr, " interface (after loading any MIBs).\n");
+ fprintf(stderr, " -x initprog If the supplied pathname exists and is a regular file,\n");
+ fprintf(stderr, " then execute it just after MIB download, with a\n");
+ fprintf(stderr, " parameter of '-d <dev>', where <dev> is as supplied\n");
+ fprintf(stderr, " by -d to this program\n");
+ exit(1);
+ }
+
+ if ((*full_init) == '2') {
+ return 0;
+ }
+
+ /* Store the mib files in our private structure. */
+ unifi_manager.mib_files_num = 0;
+ for ( ; optind < argc; optind++) {
+ sprintf(unifi_manager.mib_files[unifi_manager.mib_files_num], argv[optind]);
+ unifi_manager.mib_files_num ++;
+ }
+
+ /* Establish communication with char driver. */
+ unifi_manager.Fd = open(device, O_RDWR);
+ if (unifi_manager.Fd < 0) {
+ perror("Failed to open device");
+ exit(errno);
+ }
+
+ /* Try to initialise UniFi. */
+ sme_is_present = 0;
+ r = DD_IND_ERROR;
+ while (1) {
+ /* If we need to initialize UniFi.. */
+ if ((r == DD_IND_ERROR) && (sme_is_present == 0)) {
+ /* Try a few times */
+ for (i = 0; i < MAX_INIT_RETRIES; i++) {
+
+ /* Step1: Init H/W */
+ r = ioctl(unifi_manager.Fd, UNIFI_INIT_HW, NULL);
+ if (r < 0) {
+ perror("Step1: returned error.\n");
+ goto error;
+ }
+
+ /* If the initialisation is left to the SME, exit now. */
+ if ((*full_init) == '0') {
+ goto exit1;
+ }
+
+ /* Step2: Download initial MIBs */
+ /* Download all files on command line */
+ for (i = 0; i < unifi_manager.mib_files_num; i++) {
+ r = drv_download_mib(&unifi_manager, unifi_manager.mib_files[i]);
+ if (r != 0) {
+ perror("Step2: returned error.\n");
+ goto error;
+ }
+ }
+
+ /* Step2.5: Run optional command */
+ /* It is anticipated that this command will set extra mib values by some
+ means (e.g. omnicli) which need to be set before the first mlme_reset
+ but which also need to be changed regularly. In other words, this is for
+ testing the firmware. */
+ if (initprog) {
+ struct stat sbuf;
+
+ /* Don't complain if the lstat fails; assume this means the file does
+ not exist and skip the rest of it */
+ if (!lstat(initprog,&sbuf)) {
+ char *command;
+
+ /* However, if it exists, we should complain if things go wrong... */
+ if (!S_ISREG(sbuf.st_mode)) {
+ perror("Step 2.5: initprog not a regular file.\n");
+ goto error;
+ }
+ if (!(command=calloc(1,strlen(initprog)+strlen(device)+10))) {
+ perror("Step 2.5: calloc error\n");
+ goto error;
+ }
+ sprintf(command,"%s -d %s",initprog,device);
+ /* Don't bother with the error from the system command; let it do its own complaining */
+ system(command);
+ free(command);
+ }
+ }
+
+ /* Step3: Set MAC address */
+ r = drv_set_mac_address(&unifi_manager);
+ if (r != 0) {
+ perror("Step3: returned error.\n");
+ goto error;
+ }
+
+ /* Step4: Reset unifi */
+ r = drv_set_reset_state(&unifi_manager);
+ if (r != 0) {
+ perror("Step4: returned error.\n");
+ goto error;
+ }
+
+ /* Step5: Wait for the first MLME-CONNECT.ind */
+ r = wait_for_event(&unifi_manager, CSR_MLME_CONNECTED_INDICATION_ID);
+ if (r != 0) {
+ fprintf(stderr, "Step5: returned error.\n");
+ goto error;
+ }
+
+ /* Step6: Register the network device. */
+ r = ioctl(unifi_manager.Fd, UNIFI_INIT_NETDEV, unifi_manager.macaddress);
+ if (r < 0) {
+ fprintf(stderr, "Step10: returned error.\n");
+ r = ERROR_IO_ERROR;
+ goto error;
+ }
+
+error:
+ if (r == DD_IND_ERROR) {
+ continue;
+ }
+
+ break;
+ } /* for() */
+ }
+ /* UniFi has gone. */
+ if ((r == DD_IND_EXIT) || (r == ERROR_IO_ERROR)) {
+ break;
+ }
+ if (r == DD_SME_PRESENT) {
+ fprintf(stderr, "SME detected, manager will be idle.\n");
+ sme_is_present = 1;
+ }
+ if (r == DD_SME_NOT_PRESENT) {
+ fprintf(stderr, "Manager will handle events again.\n");
+ sme_is_present = 0;
+ }
+ /* Wait for an event from the driver. */
+ r = wait_for_event(&unifi_manager, INVALID_SIGNAL);
+ } /* while () */
+
+exit1:
+ printf("EXITING...\n");
+ /* Kill communication with driver. */
+ close(unifi_manager.Fd);
+
+ return 0;
+} /* main() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_mib.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_mib.c
new file mode 100644
index 0000000..9125568
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_mib.c
@@ -0,0 +1,431 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_mib.c
+ *
+ * Get or Set MIB data to the UniFi driver.
+ * Read data from command line and send it to the unifi driver.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <stddef.h>
+#include <sys/types.h>
+
+#include "sme_drv.h"
+#define UNION union
+#define STRUCT struct
+#define PACKING
+#include "unifiio.h"
+#include "driver/sigs.h"
+#include "driver/conversions.h"
+
+
+#define UNIFI_DO_GET_MIB 0
+#define UNIFI_DO_SET_MIB 1
+
+#define UNIFIIO_MIB_MAX_OID_LENGTH 32
+#define UNIFIIO_MIB_MAX_DATA_LENGTH 256
+#define UNIFI_MIB_TYPE_BOOL 0
+#define UNIFI_MIB_TYPE_INTEGER 1
+#define UNIFI_MIB_TYPE_OCTET_STRING 2
+#define MIB_TAG_SEQUENCE 0x30
+#define MIB_TAG_BOOLEAN 0x01
+#define MIB_TAG_INTEGER 0x02
+#define MIB_TAG_OCTETSTRING 0x04
+#define MIB_TAG_NULL 0x05
+#define MIB_TAG_COUNTER32 0x41
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * print_octet_string
+ *
+ * Fucntion to format OCTET_STRING data for printing.
+ *
+ * Arguments:
+ * data, data_len
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+static char *
+print_octet_string(unsigned char *data, int data_len)
+{
+ /* Allow 3 chars per byte for xx-xx-xx format */
+ static char buf[UNIFIIO_MIB_MAX_DATA_LENGTH * 3];
+ char *p;
+ int n;
+
+ if (data_len == 0) {
+ return "";
+ }
+
+ p = buf;
+ n = sprintf(p, "%02X", *data++);
+ p += n;
+ data_len--;
+
+ while (data_len--) {
+ n = sprintf(p, "-%02X", *data++);
+ p += n;
+ }
+
+ return buf;
+} /* print_octet_string() */
+
+
+void print_mib_value(unsigned char *value, int value_len, int mibtype)
+{
+ if (mibtype == UNIFI_MIB_TYPE_BOOL) {
+ printf("B %d\n", (int)(*value) ? 1 : 0);
+ } else if (mibtype == UNIFI_MIB_TYPE_INTEGER) {
+ printf("I %d\n", *((int*)value));
+ } else if (mibtype == UNIFI_MIB_TYPE_OCTET_STRING) {
+ printf("S %s\n", print_octet_string(value, value_len));
+ } else {
+ printf("*\n");
+ }
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * query_mib
+ *
+ * desc
+ *
+ * Arguments:
+ * None.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+int
+query_mib(int fd, char *oid_str, int mibtype)
+{
+ unsigned char varbind[MAX_VARBIND_LENGTH];
+ unsigned char *ptr;
+ int len;
+ int rc;
+
+ /* Build a varbind of OID and INTEGER */
+ varbind[0] = MIB_TAG_SEQUENCE;
+ ptr = varbind + 2; /* assumes length will always be one octet */
+
+ /* Build the MLME-GET.req */
+ len = MibEncodeOID(oid_str, ptr);
+ len += MibEncodeNull(ptr+len);
+ varbind[1] = len;
+
+ if (len > 0) {
+ rc = ioctl(fd, UNIFI_GET_MIB, varbind);
+ if (rc < 0) {
+ perror("ioctl UNIFI_GET_MIB failed");
+ return rc;
+ }
+ } else {
+ perror("ioctl UNIFI_GET_MIB failed. Empty request.");
+ return -1;
+ }
+
+ /* Retrieve the response from UniFi */
+ {
+ int value_int;
+ uint32 value_boolean;
+ unsigned char value_string[256];
+ int value_string_len;
+ unsigned char *ptr;
+
+ /* Find the appended bulk data */
+ ptr = varbind;
+
+ /* Skip over the varbind SEQUENCE tag */
+ ptr += 2;
+ /* Skip over the OID */
+ ptr += ptr[1] + 2;
+
+ value_string_len = ptr[1];
+
+ if ((ptr[0] == MIB_TAG_INTEGER) ||
+ (ptr[0] == MIB_TAG_COUNTER32))
+ {
+ /*
+ * Treat counters as integer.
+ * Override the type field so MibDecodeInteger does the right thing.
+ */
+ ptr[0] = MIB_TAG_INTEGER;
+ if (MibDecodeInteger(ptr, &value_int) != 0) {
+ print_mib_value((unsigned char*)&value_int, 0, UNIFI_MIB_TYPE_INTEGER);
+ }
+ } else if (ptr[0] == MIB_TAG_BOOLEAN) {
+ if (MibDecodeBoolean(ptr, &value_boolean) != 0) {
+ print_mib_value((unsigned char*)&value_boolean, 0, UNIFI_MIB_TYPE_BOOL);
+ }
+ } else if (ptr[0] == MIB_TAG_OCTETSTRING) {
+ if (MibDecodeOctetString(ptr, value_string_len, value_string) != 0) {
+ print_mib_value(value_string, value_string_len, UNIFI_MIB_TYPE_OCTET_STRING);
+ }
+ } else {
+ /* unexpected type of return value */
+ printf("unrecognised MIB type: %d\n", ptr[0]);
+ }
+ }
+
+
+ return 0;
+} /* query_mib() */
+
+
+int
+set_mib_int(int fd, char *oid_str, int set_int, int mib_type)
+{
+ unsigned char varbind[MAX_VARBIND_LENGTH];
+ unsigned char *ptr;
+ int len;
+ int rc;
+
+ /* Build a varbind of OID and INTEGER */
+ varbind[0] = MIB_TAG_SEQUENCE;
+ ptr = varbind + 2; /* assumes length will always be one octet */
+
+ /* Build the MLME-GET.req */
+ len = MibEncodeOID(oid_str, ptr);
+ if (mib_type == UNIFI_MIB_TYPE_INTEGER) {
+ len += MibEncodeInteger(set_int, (ptr+len));
+ } else if (mib_type == UNIFI_MIB_TYPE_BOOL) {
+ len += MibEncodeBoolean(set_int, (ptr+len));
+ } else {
+ return -1;
+ }
+ varbind[1] = len;
+
+ if (len > 0) {
+ rc = ioctl(fd, UNIFI_SET_MIB, varbind);
+ if (rc < 0) {
+ perror("ioctl UNIFI_SET_MIB failed");
+ return rc;
+ }
+ } else {
+ perror("ioctl UNIFI_SET_MIB failed. Empty request.");
+ return -1;
+ }
+
+ return 0;
+} /* set_mib_int() */
+
+
+int
+set_mib_string(int fd, char *oid_str, char* set_str, int set_str_len)
+{
+ unsigned char varbind[MAX_VARBIND_LENGTH + 256];
+ unsigned char *ptr;
+ int len;
+ int rc;
+
+ /* Build a varbind of OID and INTEGER */
+ varbind[0] = MIB_TAG_SEQUENCE;
+ ptr = varbind + 2; /* assumes length will always be one octet */
+
+ /* Build the MLME-GET.req */
+ len = MibEncodeOID(oid_str, ptr);
+ len += MibEncodeOctetString((unsigned char*)set_str, set_str_len, (ptr+len));
+ varbind[1] = len;
+
+ if (len > 0) {
+ rc = ioctl(fd, UNIFI_SET_MIB, varbind);
+ if (rc < 0) {
+ perror("ioctl UNIFI_SET_MIB failed");
+ return rc;
+ }
+ } else {
+ perror("ioctl UNIFI_SET_MIB failed. Empty request.");
+ return -1;
+ }
+
+ return 0;
+} /* set_mib_string() */
+
+static int
+read_byte(char *p, unsigned char *b)
+{
+ int n = 0;
+ int i, c, v;
+
+ /* Use a loop so we accept single digit fields */
+ v = 0;
+ for (i = 0; i < 2; i++) {
+
+ c = *p++;
+
+ if ((c >= '0') && (c <= '9')) {
+ c -= '0';
+ } else if ((c >= 'A') && (c <= 'F')) {
+ c = c - 'A' + 10;
+ } else if ((c >= 'a') && (c <= 'f')) {
+ c = c - 'a' + 10;
+ } else {
+ break;
+ }
+
+ v = (v * 16) + c;
+ n++;
+ }
+
+ if (n) {
+ *b = v;
+ }
+
+ return n;
+} /* read_byte() */
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * main
+ *
+ * C entry point
+ *
+ * Arguments:
+ * argc, argv command line args
+ *
+ * Returns:
+ * exit code
+ * ---------------------------------------------------------------------------
+ */
+int
+main(int argc, char **argv)
+{
+ int fd;
+ char *device = "/dev/unifiudi0";
+ char *query_str = NULL;
+ int set_int = 0;
+ char *set_str=NULL, *c, *x;
+ int set_str_len = 0;
+ int mib_type = UNIFI_MIB_TYPE_INTEGER;
+ int request_type = UNIFI_DO_GET_MIB;
+ int err = 0, i, j, r;
+
+ /* The other args on the line specify options to be set... */
+ for(i = 1; i < argc; i ++)
+ {
+ if (!strcasecmp(argv[i], "dev")) {
+ device = argv[i+1];
+ i += 2;
+ }
+
+ if (!strcasecmp(argv[i], "mode")) {
+ if (!strcasecmp(argv[i+1], "get")) {
+ request_type = UNIFI_DO_GET_MIB;
+ query_str = argv[i+2];
+ break;
+ } else if (!strcasecmp(argv[i+1], "set")){
+ request_type = UNIFI_DO_SET_MIB;
+ query_str = argv[i+2];
+ i += 2;
+ }
+ }
+
+ if (!strcasecmp(argv[i], "type")) {
+ if (!strcasecmp(argv[i+1], "int")) {
+ mib_type = UNIFI_MIB_TYPE_INTEGER;
+ if(sscanf(argv[i+2], "%d", &set_int) != 1) {
+ perror("Read integer value failed\n");
+ }
+ } else if (!strcasecmp(argv[i+1], "bool")){
+ mib_type = UNIFI_MIB_TYPE_BOOL;
+ if(sscanf(argv[i+2], "%d", &set_int) != 1) {
+ perror("Read boolean value failed\n");
+ }
+ } else if (!strcasecmp(argv[i+1], "string")) {
+ mib_type = UNIFI_MIB_TYPE_OCTET_STRING;
+
+ if (argv[i+2] != NULL) {
+ x = argv[i+2];
+ set_str_len = strlen(argv[i+2])/2;
+ c = set_str = (char*)malloc(set_str_len);
+ for ( j = 0; j < (set_str_len*2); j+=2, x+=2, c++) {
+ read_byte(x, (unsigned char*)c);
+ }
+ } else {
+ fprintf(stderr, "Empty set string.\n");
+ err++;
+ }
+ }
+ i += 2;
+ }
+ }
+
+ if ((query_str == NULL)) {
+ fprintf(stderr, "Empty request oid\n");
+ err++;
+ }
+ if (err) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " unifi_mib [dev dev] mode get|set oid type int|bool|string N|{ N N .. }\n");
+ fprintf(stderr, " Query or set the value of the given Object ID (e.g. 1.2.840.10036.2.1.1.1.1)\n");
+ fprintf(stderr, " mode gives the operation type (get or set)\n");
+ fprintf(stderr, " type gives the data type: bool, int, string\n");
+ fprintf(stderr, " dev dev Use <dev> as the device (default is /dev/unifi0).\n");
+ fprintf(stderr, "For example: \n");
+ fprintf(stderr, " unifi_mib mode get 1.2.840.10036.2.2.1.4.1 type int\n");
+ exit(1);
+ }
+
+ fd = open(device, O_RDWR);
+ if (fd < 0) {
+ perror("Failed to open device (Hint: make sure you are root).");
+ exit(1);
+ }
+
+ if (request_type == UNIFI_DO_GET_MIB)
+ {
+ if (query_str) {
+ /* Query mode */
+ query_mib(fd, query_str, mib_type);
+ }
+ } else {
+ if (mib_type == UNIFI_MIB_TYPE_INTEGER) {
+ r = set_mib_int(fd, query_str, set_int, mib_type);
+ if (r < 0) {
+ printf("set_mib_int: failed\n");
+ }
+ } else if (mib_type == UNIFI_MIB_TYPE_BOOL) {
+ r = set_mib_int(fd, query_str, set_int, mib_type);
+ if (r < 0) {
+ printf("set_mib_int: failed\n");
+ }
+ } else if (mib_type == UNIFI_MIB_TYPE_OCTET_STRING) {
+ if (set_str != NULL) {
+ r = set_mib_string(fd, query_str, set_str, set_str_len);
+ if (r < 0) {
+ printf("set_mib_string: failed\n");
+ }
+ }
+ }
+ }
+
+ if (set_str != NULL) {
+ free(set_str);
+ }
+ close(fd);
+
+ return 0;
+}
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest.c
new file mode 100644
index 0000000..42fd725
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest.c
@@ -0,0 +1,198 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_config.c
+ *
+ * Get/Set configuration to the UniFi driver.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <stddef.h>
+
+#include "osa_types.h"
+#include "unifiio.h"
+
+#include "unifi_putest_lib.h"
+
+
+int read16(int fd, unsigned int address, uint16 *value)
+{
+ struct unifi_putest_cmd52 cmd52_params;
+ unsigned char lo = 0xAD, hi = 0xDE;
+ int r;
+
+ cmd52_params.funcnum = 1;
+ cmd52_params.addr = address;
+ cmd52_params.data = lo;
+ r = unifi_putest_cmd52_read(fd, &cmd52_params);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_CMD52_READ: failed\n");
+ return r;
+ }
+
+ lo = cmd52_params.data;
+
+ cmd52_params.funcnum = 1;
+ cmd52_params.addr = address + 1;
+ cmd52_params.data = hi;
+ r = unifi_putest_cmd52_read(fd, &cmd52_params);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_CMD52_READ: failed\n");
+ return r;
+ }
+
+ hi = cmd52_params.data;
+ *value = (((uint16)hi) << 8) | lo;
+
+ return 0;
+}
+
+
+int write16(int fd, unsigned int address, uint16 value)
+{
+ struct unifi_putest_cmd52 cmd52_params;
+ int r;
+
+ cmd52_params.funcnum = 1;
+ cmd52_params.addr = address + 1;
+ cmd52_params.data = (unsigned char)(value >> 8);
+ r = unifi_putest_cmd52_write(fd, &cmd52_params);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_CMD52_WRITE: failed\n");
+ return r;
+ }
+
+ cmd52_params.funcnum = 1;
+ cmd52_params.addr = address;
+ cmd52_params.data = (unsigned char)value;
+ r = unifi_putest_cmd52_write(fd, &cmd52_params);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_CMD52_WRITE: failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+static int Cmd52Test(int fd)
+{
+ uint16 reply;
+ int n, r;
+
+ /* select MAC processor DBG_HOST_PROC_SELECT */
+ r = write16(fd, 0x1fd20, 0 );
+ if (r) {
+ printf("CMD52 Test Failed\n");
+ return -1;
+ }
+
+ /* set up memory window 0x233 */
+ r = write16(fd, 0x1fcf0, 0x233);
+ if (r) {
+ printf("CMD52 Test Failed\n");
+ return -1;
+ }
+
+ for ( n = 0; n < 10; n++ )
+ {
+ uint16 data = (0x06AD << n) + n;
+ r = write16(fd, 0x4000 + 0x0fb0, data);
+ if (r) {
+ printf("CMD52 Test Failed\n");
+ return -1;
+ }
+
+ r = read16(fd, 0x4000 + 0x0fb0, &reply);
+ if (r) {
+ printf("CMD52 Test Failed\n");
+ return -1;
+ }
+
+ if (data != reply)
+ {
+ printf("Fail at %d, expected: %04x observed: %04x\n", n, data, reply);
+ return -1;
+ }
+ }
+
+ printf("CMD52 Test Succeed\n");
+ return 0;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ char device[] = "/dev/unifiudi0";
+ int r;
+ int fd;
+ int clock_khz;
+
+ fd = unifi_putest_init(device);
+ if (fd < 0) {
+ perror("Failed to open device");
+ exit(errno);
+ }
+
+ r = unifi_putest_start(fd);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_START: failed\n");
+ goto EXIT;
+ }
+
+ sleep(1);
+
+ clock_khz = 25000;
+ r = unifi_putest_set_sdio_clock(fd, clock_khz);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_SDIO_CLOCK: failed\n");
+ goto EXIT;
+ }
+
+ r = Cmd52Test(fd);
+ if (r < 0) {
+ goto EXIT;
+ }
+
+ r = unifi_putest_dl_fw(fd, "putest_sta.xbv", 14);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_DL_FW: failed\n");
+ goto EXIT;
+ }
+
+ r = Cmd52Test(fd);
+ if (r < 0) {
+ goto EXIT;
+ }
+
+EXIT:
+ r = unifi_putest_stop(fd);
+ if (r < 0) {
+ printf("UNIFI_PUTEST_STOP: failed\n");
+ }
+
+ /* Kill communication with driver. */
+ unifi_putest_deinit(fd);
+
+ return r;
+} /* main() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.c
new file mode 100644
index 0000000..bdd3d2d
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.c
@@ -0,0 +1,190 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_putest_lib.c
+ *
+ * Sets putest ioctls to the UniFi driver.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <stddef.h>
+
+#include "osa_types.h"
+#include "unifiio.h"
+
+
+int unifi_putest_init(char *device)
+{
+ int fd;
+
+ /* Start communication with driver. */
+ fd = open(device, O_RDWR);
+ if (fd < 0) {
+ printf("Failed to open device\n");
+ }
+ return fd;
+}
+
+int unifi_putest_deinit(int fd)
+{
+ /* Kill communication with driver. */
+ close(fd);
+
+ return 0;
+}
+
+int unifi_putest_start(int fd)
+{
+ unsigned char buffer[8];
+ int r;
+
+ *((unifi_putest_command_t*)buffer) = UNIFI_PUTEST_START;
+
+ r = ioctl(fd, UNIFI_PUTEST, buffer);
+ if (r < 0) {
+ printf("UNIFI_PUTEST: Start failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+int unifi_putest_stop(int fd)
+{
+ unsigned char buffer[8];
+ int r;
+
+ *((unifi_putest_command_t*)buffer) = UNIFI_PUTEST_STOP;
+
+ r = ioctl(fd, UNIFI_PUTEST, buffer);
+ if (r < 0) {
+ printf("UNIFI_PUTEST: Stop failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+int unifi_putest_set_sdio_clock(int fd, int clock_khz)
+{
+ unsigned char buffer[32];
+ uint8 *buf_pos;
+ int r;
+
+ buf_pos = buffer;
+ *((unifi_putest_command_t*)buf_pos) = UNIFI_PUTEST_SET_SDIO_CLOCK;
+
+ buf_pos += sizeof(unifi_putest_command_t);
+ *((int*)buf_pos) = clock_khz;
+
+ r = ioctl(fd, UNIFI_PUTEST, buffer);
+ if (r < 0) {
+ printf("UNIFI_PUTEST: Set Clock failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+int unifi_putest_cmd52_read(int fd, struct unifi_putest_cmd52 *cmd52_params)
+{
+ unsigned char buffer[32];
+ uint8 *buf_pos;
+ int r;
+
+ buf_pos = buffer;
+ *((unifi_putest_command_t*)buf_pos) = UNIFI_PUTEST_CMD52_READ;
+
+ buf_pos += sizeof(unifi_putest_command_t);
+ *((unsigned int*)buf_pos) = sizeof(struct unifi_putest_cmd52);
+
+ buf_pos += sizeof(unsigned int);
+ memcpy(buf_pos, cmd52_params, sizeof(struct unifi_putest_cmd52));
+
+ r = ioctl(fd, UNIFI_PUTEST, buffer);
+ if (r < 0) {
+ printf("UNIFI_PUTEST: CMD52 Read failed\n");
+ return r;
+ }
+
+ /* Copy the result back to the buffer */
+ memcpy(cmd52_params, buf_pos, sizeof(struct unifi_putest_cmd52));
+
+ return 0;
+}
+
+int unifi_putest_cmd52_write(int fd, struct unifi_putest_cmd52 *cmd52_params)
+{
+ unsigned char buffer[32];
+ uint8 *buf_pos;
+ int r;
+
+ buf_pos = buffer;
+ *((unifi_putest_command_t*)buf_pos) = UNIFI_PUTEST_CMD52_WRITE;
+
+ buf_pos += sizeof(unifi_putest_command_t);
+ *((unsigned int*)buf_pos) = sizeof(struct unifi_putest_cmd52);
+
+ buf_pos += sizeof(unsigned int);
+ memcpy(buf_pos, cmd52_params, sizeof(struct unifi_putest_cmd52));
+
+ r = ioctl(fd, UNIFI_PUTEST, buffer);
+ if (r < 0) {
+ printf("UNIFI_PUTEST: CMD52 Write failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
+int unifi_putest_dl_fw(int fd, const char *fw_file_name,
+ unsigned int fw_file_name_len)
+{
+ unsigned char buffer[32];
+ uint8 *buf_pos;
+ int r;
+#define UF_PUTEST_MAX_FW_FILE_NAME 16
+
+ if (fw_file_name_len > UF_PUTEST_MAX_FW_FILE_NAME) {
+ printf("unifi_putest_start: f/w file name exceeds UF_PUTEST_MAX_FW_FILE_NAME\n");
+ return -EINVAL;
+ }
+
+ buf_pos = buffer;
+ *((unifi_putest_command_t*)buf_pos) = UNIFI_PUTEST_DL_FW;
+
+ buf_pos += sizeof(unifi_putest_command_t);
+ *((unsigned int*)buf_pos) = fw_file_name_len;
+
+ buf_pos += sizeof(unsigned int);
+ memcpy(buf_pos, fw_file_name, fw_file_name_len);
+
+ r = ioctl(fd, UNIFI_PUTEST, buffer);
+ if (r < 0) {
+ printf("UNIFI_PUTEST: Start failed\n");
+ return r;
+ }
+
+ return 0;
+}
+
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.h b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.h
new file mode 100644
index 0000000..5931058
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_putest_lib.h
@@ -0,0 +1,30 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_config_lib.h
+ *
+ * Get/Set configuration to the UniFi driver library.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#ifndef UNIFI_PUTEST_LIB_H
+#define UNIFI_PUTEST_LIB_H
+
+
+int unifi_putest_init(char *device);
+int unifi_putest_deinit(int fd);
+int unifi_putest_start(int fd);
+int unifi_putest_stop(int fd);
+int unifi_putest_set_sdio_clock(int fd, int clock_khz);
+int unifi_putest_cmd52_read(int fd, struct unifi_putest_cmd52 *cmd52_params);
+int unifi_putest_cmd52_write(int fd, struct unifi_putest_cmd52 *cmd52_params);
+int unifi_putest_dl_fw(int fd, const char *fw_file_name, unsigned int fw_file_name_len);
+
+
+#endif /* UNIFI_PUTEST_LIB_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_qos.c b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_qos.c
new file mode 100644
index 0000000..ac81668
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unifi_qos.c
@@ -0,0 +1,346 @@
+/*
+ * ***************************************************************************
+ *
+ * FILE: unifi_qos.c
+ *
+ * Configure WMM-PS and PERIODIC TRAFFIC parameters.
+ *
+ * Copyright (C) 2008 by Cambridge Silicon Radio Ltd.
+ *
+ * Refer to LICENSE.txt included with this source code for details on
+ * the license terms.
+ *
+ * ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <stddef.h>
+
+#include "osa_types.h"
+#include "hostio/hip_fsm_types.h"
+#include "smeio/smeio_fsm_types.h"
+#include "unifiio.h"
+
+
+#if 0
+#define WMMPS_UNKNOWN 0xFFF0
+#define WMMPS_OFF 0x0000
+#define WMMPS_AC_BK 0x0001
+#define WMMPS_AC_BE 0x0002
+#define WMMPS_AC_VI 0x0004
+#define WMMPS_AC_VO 0x0008
+#endif
+
+#define COEX_CONFIG_VALUE_UNKNOWN 0xFFFF
+
+
+int
+main(int argc, char **argv)
+{
+ char *device = "/dev/unifiudi0";
+ int start = 0;
+ int err, i;
+ int r = 0;
+ int fd = -1;
+ unifi_CoexConfig *coex_config;
+ unsigned char *ioctl_req_buffer;
+
+// unsigned int wmmps = WMMPS_UNKNOWN;
+ unsigned int coex = COEX_CONFIG_VALUE_UNKNOWN;
+ unsigned int afh_channel = COEX_CONFIG_VALUE_UNKNOWN;
+ unsigned int advanced_coex = COEX_CONFIG_VALUE_UNKNOWN;
+ unsigned int scheme_mgt = COEX_CONFIG_VALUE_UNKNOWN;
+ unsigned int periodic_direction = COEX_CONFIG_VALUE_UNKNOWN;
+ unsigned int periodic_wake = COEX_CONFIG_VALUE_UNKNOWN;
+ unsigned int periodic_bursty_latency_ms = 0;
+ unsigned int periodic_continuous_latency_ms = 0;
+
+ err = 0;
+ if (argc > 1) {
+ if (!strcasecmp(argv[1], "--help")) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " unifi_qos dev /dev/unifiN \n");
+// fprintf(stderr, " [ wmmps {off|ac_bk|ac_be|ac_vi|ac_vo} ] \n");
+ fprintf(stderr, " [coex off|on] \n");
+ fprintf(stderr, " [afh_channel off|on] \n");
+ fprintf(stderr, " [advanced off|on] \n");
+ fprintf(stderr, " [scheme_mgt off|on] \n");
+ fprintf(stderr, " [direction {input|output}] \n");
+ fprintf(stderr, " [wake {off|on}] \n");
+ fprintf(stderr, " [bursty N (latency in msec)] \n");
+ fprintf(stderr, " [continuous N (latency in msec)] \n");
+ fprintf(stderr, " [--show] \n");
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ }
+
+ /* The other args on the line specify options to be set... */
+ for(i = 1; i < argc; i ++)
+ {
+ if (!strcasecmp(argv[i], "dev")) {
+ device = argv[i+1];
+ i += 2;
+ }
+
+#if 0
+ if (!strcasecmp(argv[i], "wmmps")) {
+ start = 1;
+ for (j=i+1; j < argc; j++) {
+ if (!strcasecmp(argv[j], "off")) {
+ wmmps = WMMPS_OFF;
+ i = j;
+ break;
+ } else if (!strcasecmp(argv[j], "ac_bk")) {
+ wmmps |= WMMPS_AC_BK;
+ } else if (!strcasecmp(argv[j], "ac_be")) {
+ wmmps |= WMMPS_AC_BE;
+ } else if (!strcasecmp(argv[j], "ac_vi")) {
+ wmmps |= WMMPS_AC_VI;
+ } else if (!strcasecmp(argv[j], "ac_vo")) {
+ wmmps |= WMMPS_AC_VO;
+ } else {
+ i = j - 1;
+ break;
+ }
+ }
+ }
+#endif
+ if (!strcasecmp(argv[i], "--show")) {
+ start = 2;
+ break;
+ }
+
+ if (!strcasecmp(argv[i], "coex")) {
+ if (!strcasecmp(argv[i+1], "off")) {
+ start = 1;
+ coex = 0;
+ i++;
+ } else if (!strcasecmp(argv[i+1], "on")) {
+ start = 1;
+ coex = 1;
+ i++;
+ } else {
+ start = 0;
+ break;
+ }
+ }
+
+ if (!strcasecmp(argv[i], "afh_channel")) {
+ if (!strcasecmp(argv[i+1], "off")) {
+ start = 1;
+ afh_channel = 0;
+ i++;
+ } else if (!strcasecmp(argv[i+1], "on")) {
+ start = 1;
+ afh_channel = 1;
+ i++;
+ } else {
+ start = 0;
+ break;
+ }
+ }
+
+ if (!strcasecmp(argv[i], "advanced")) {
+ if (!strcasecmp(argv[i+1], "off")) {
+ start = 1;
+ advanced_coex = 0;
+ i++;
+ } else if (!strcasecmp(argv[i+1], "on")) {
+ start = 1;
+ advanced_coex = 1;
+ i++;
+ } else {
+ start = 0;
+ break;
+ }
+ }
+
+ if (!strcasecmp(argv[i], "scheme_mgt")) {
+ if (!strcasecmp(argv[i+1], "off")) {
+ start = 1;
+ scheme_mgt = 0;
+ i++;
+ } else if (!strcasecmp(argv[i+1], "on")) {
+ start = 1;
+ scheme_mgt = 1;
+ i++;
+ } else {
+ start = 0;
+ break;
+ }
+ }
+
+ if (!strcasecmp(argv[i], "direction")) {
+ if (!strcasecmp(argv[i+1], "input")) {
+ start = 1;
+ periodic_direction = 0;
+ i++;
+ } else if (!strcasecmp(argv[i+1], "output")) {
+ start = 1;
+ periodic_direction = 1;
+ i++;
+ } else {
+ start = 0;
+ break;
+ }
+ }
+
+ if (!strcasecmp(argv[i], "wake")) {
+ if (!strcasecmp(argv[i+1], "off")) {
+ start = 1;
+ periodic_wake = 0;
+ i++;
+ } else if (!strcasecmp(argv[i+1], "on")) {
+ start = 1;
+ periodic_wake = 1;
+ i++;
+ } else {
+ start = 0;
+ break;
+ }
+ }
+
+ if (!strcasecmp(argv[i], "bursty")) {
+ sscanf(argv[i+1], "%d", &periodic_bursty_latency_ms);
+ i++;
+ }
+
+ if (!strcasecmp(argv[i], "continuous")) {
+ sscanf(argv[i+1], "%d", &periodic_continuous_latency_ms);
+ i++;
+ }
+
+ }
+ if (start == 0) {
+ fprintf(stderr, "Type \"unifi_qos --help\" to get options.\n");
+ return 0;
+ }
+
+ fprintf(stderr, " Using:\n");
+ fprintf(stderr, " DEVICE: %s\n", device);
+// fprintf(stderr, " WMMPS: 0x%x\n", wmmps);
+ if (start == 1) {
+ fprintf(stderr, " Coex Enable : %s\n",
+ (coex == 1) ? "On" : ((coex == 0) ? "Off" : "Unspecified"));
+ fprintf(stderr, " Afh Channel Enable : %s\n",
+ (afh_channel == 1) ? "On" : ((afh_channel == 0) ? "Off" : "Unspecified"));
+ fprintf(stderr, " Coex Advanced Enable : %s\n",
+ (advanced_coex == 1) ? "On" : ((advanced_coex == 0) ? "Off" : "Unspecified"));
+ fprintf(stderr, " Scheme Management Enable : %s\n",
+ (scheme_mgt == 1) ? "On" : ((scheme_mgt == 0) ? "Off" : "Unspecified"));
+ fprintf(stderr, " Periodic Direction: %s\n",
+ (periodic_direction == 1) ? "Output" : ((periodic_direction == 0) ? "Input" : "Unspecified"));
+ fprintf(stderr, " Periodic Wake Host: %s\n",
+ (periodic_wake == 1) ? "On" : ((periodic_wake == 0) ? "Off" : "Unspecified"));
+ fprintf(stderr, " Periodic BURSTY Max Latency %d msec \n",
+ periodic_bursty_latency_ms);
+ fprintf(stderr, " Periodic CONTINUOUS Max Latency %d msec \n",
+ periodic_continuous_latency_ms);
+ fprintf(stderr, "\n");
+ }
+
+ /* Establish communication with char driver. */
+ fd = open(device, O_RDWR);
+ if (fd < 0) {
+ perror("Failed to open device");
+ exit(errno);
+ }
+
+#if 0
+ if (wmmps != WMMPS_UNKNOWN) {
+ wmmps &= ~WMMPS_UNKNOWN;
+ r = ioctl(fd, UNIFI_CFG_UAPSD_TRAFFIC, &wmmps);
+ if (r < 0) {
+ printf("UNIFI_CFG_UAPSD_TRAFFIC: failed\n");
+ goto EXIT;
+ } else {
+ printf("UNIFI_CFG_UAPSD_TRAFFIC: New mask 0x%x\n", wmmps);
+ }
+ }
+#endif
+
+ ioctl_req_buffer = (unsigned char*) malloc(sizeof(unsigned char) + sizeof(unifi_CoexConfig));
+ if (ioctl_req_buffer == NULL) {
+ goto EXIT;
+ }
+
+ ioctl_req_buffer[0] = 0;
+ r = ioctl(fd, UNIFI_CFG_PERIOD_TRAFFIC, ioctl_req_buffer);
+ if (r < 0) {
+ printf("UNIFI_CFG_PERIOD_TRAFFIC: get failed\n");
+ goto EXIT;
+ }
+
+ coex_config = (unifi_CoexConfig*) (ioctl_req_buffer + 1);
+
+ if (start == 2) {
+ printf("coexEnable = %d \n", coex_config->coexEnable);
+ printf("coexAfhChannelEnable = %d \n", coex_config->coexAfhChannelEnable);
+ printf("coexAdvancedEnable = %d \n", coex_config->coexAdvancedEnable);
+ printf("coexEnableSchemeManagement = %d \n", coex_config->coexEnableSchemeManagement);
+ printf("coexDirection = %d \n", coex_config->coexDirection);
+ printf("coexPeriodicWakeHost = %d \n", coex_config->coexPeriodicWakeHost);
+ printf("coexTrafficBurstyLatencyMs = %d \n", coex_config->coexTrafficBurstyLatencyMs);
+ printf("coexTrafficContinuousLatencyMs = %d \n", coex_config->coexTrafficContinuousLatencyMs);
+
+ goto EXIT;
+ }
+
+ if (coex != COEX_CONFIG_VALUE_UNKNOWN) {
+ coex_config->coexEnable = coex;
+ }
+ if (afh_channel != COEX_CONFIG_VALUE_UNKNOWN) {
+ coex_config->coexAfhChannelEnable = afh_channel;
+ }
+ if (advanced_coex != COEX_CONFIG_VALUE_UNKNOWN) {
+ coex_config->coexAdvancedEnable = advanced_coex;
+ }
+ if (scheme_mgt != COEX_CONFIG_VALUE_UNKNOWN) {
+ coex_config->coexEnableSchemeManagement = scheme_mgt;
+ }
+ if (periodic_direction != COEX_CONFIG_VALUE_UNKNOWN) {
+ if (periodic_direction == 1) {
+ coex_config->coexDirection = unifi_CoexDirectionDot11Output;
+ } else if (periodic_direction == 0) {
+ coex_config->coexDirection = unifi_CoexDirectionDot11Input;
+ }
+ }
+ if (periodic_wake != COEX_CONFIG_VALUE_UNKNOWN) {
+ coex_config->coexPeriodicWakeHost = periodic_wake;
+ }
+ if (periodic_bursty_latency_ms) {
+ coex_config->coexTrafficBurstyLatencyMs = periodic_bursty_latency_ms;
+ }
+ if (periodic_continuous_latency_ms) {
+ coex_config->coexTrafficContinuousLatencyMs = periodic_continuous_latency_ms;
+ }
+
+ ioctl_req_buffer[0] = 1;
+ r = ioctl(fd, UNIFI_CFG_PERIOD_TRAFFIC, ioctl_req_buffer);
+ if (r < 0) {
+ printf("UNIFI_CFG_PERIOD_TRAFFIC: Set failed\n");
+ }
+EXIT:
+
+ printf("EXITING...\n");
+ if (ioctl_req_buffer != NULL) {
+ free(ioctl_req_buffer);
+ }
+ /* Kill communication with driver. */
+ close(fd);
+
+ return r;
+} /* main() */
+
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unififw b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unififw
new file mode 100755
index 0000000..9b1f08c
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/tools/unififw
@@ -0,0 +1,117 @@
+#! /bin/sh
+# Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
+# /usr/sbin/unififw
+# This is run from the driver via kerneld when a UniFi card
+# is inserted.
+#
+# Usage: unififw [instance]
+# [instance] optional instance number of card. "0" for first card,
+# "1" for second card.
+#
+# Old usage: unififw <device> <instance> <hwid>
+# <device> one of unifi_sdio or unifi_pci
+# <instance> card instance number. For SDIO this is the slot
+# number of the card
+# <hwid> The h/w revision string from the card.
+#
+
+# Run body of script in a sub-shell so we can pipe output into logger
+(
+
+# Backwards-compatibility, drop any <device> arg
+case "$1" in
+ unifi_sdio | unifi_pci) shift ;;
+esac
+
+instance="0"
+if [ -n "$1" ]; then
+ instance="$1"
+fi
+case "$instance" in
+ "0"|"1") ;;
+ *) echo "Bad device instance"
+ exit 1
+ ;;
+esac
+
+init_mode="$2"
+
+# Set up local vars
+dev=/dev/unifi${instance}
+fwpath=/lib/firmware/unifi-sdio-${instance}
+
+
+# Find files for:
+# localmib.dat - any local additions
+# ufmib.dat - standard MIB for the h/w
+# mac.txt - MAC address (in text format)
+# initprog - optional program which can do things before first MLME reset
+
+localmib=$fwpath/localmib.dat
+if [ ! -f ${localmib} ]; then
+localmib=""
+fi
+
+mibfile=$fwpath/ufmib.dat
+[ -f ${mibfile} ] || mibfile=
+
+## If we have an initprog and it's executable, supply the -x parameter
+## to unifi_manager. The main purpose of this is to allow some MIB
+## parameters which need setting prior to the first MLME reset to be
+## set by the test system without having to rewrite ufmib.dat on the
+## fly.
+initprog=""
+[ -x "${fwpath}/initprog" ] && initprog="-x ${fwpath}/initprog"
+
+# Fallback to the broadcast MAC addr, which UniFi takes to mean "use the
+# MAC address from MIB", typically read from EEPROM
+macaddr="FF:FF:FF:FF:FF:FF"
+macfile=$fwpath/mac.txt
+if [ -f $macfile ]; then
+ macaddr=`cat $macfile`
+fi
+
+
+# init_mode==2 means an SME userspace build
+if [ "${init_mode}" = "2" ]; then
+ mibfileparam=-mib=$fwpath/ufmib.dat
+ [ -f $fwpath/ufmib.dat ] || mibfileparam=
+
+ localmibfileparam=-mib=$fwpath/localmib.dat
+ [ -f $fwpath/localmib.dat ] || localmibfileparam=
+
+ macfileparam=-mac=$macfile
+ [ -f $macfile ] || macfileparam=
+
+ result=0
+ retries=0
+
+ while [ "$retries" -lt "3" ]; do
+ /usr/sbin/unifi_helper -dev=$dev -wifion $macfileparam $mibfileparam $localmibfileparam
+ result=$?
+ [ "$result" -ne "0" ] || exit 0
+ sleep 1
+ retries=`expr $retries + 1`
+ if [ "$result" -lt "0" ]; then
+ retries=0
+ fi
+ echo "unifi_helper -dev=$dev -wifion $macfileparam $mibfileparam $localmibfileparam result: $result"
+ done
+ exit 0
+fi
+
+# This is a bit of a hack. When we have no firmware, sometimes when we
+# run unifi_manager the device nodes are not there yet, and it fails.
+# I guess this is some sort of a race, but I odn't know how to fix it.
+sleep 0.25
+
+# Set the MAC address, MIB(s) and start the driver.
+/usr/sbin/unifi_manager -d $dev -s $macaddr -b $init_mode $initprog $mibfile $localmib || {
+ result=$?
+ echo "unifi_manager -d $dev -s $macaddr -b $init_mode $initprog $mibfile $localmib failed: $result"
+ exit 2
+}
+
+) 2>&1 | logger -t unififw -p daemon.notice
+
+exit 0
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.5.11_csr.patch b/unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.5.11_csr.patch
new file mode 100644
index 0000000..542282f
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.5.11_csr.patch
@@ -0,0 +1,128 @@
+diff -uNr wpa_supplicant-0.5.11/driver_wext.c wpa_supplicant-0.5.11_mod/driver_wext.c
+--- wpa_supplicant-0.5.11/driver_wext.c 2008-02-19 23:59:22.000000000 +0000
++++ wpa_supplicant-0.5.11_mod/driver_wext.c 2008-03-25 12:07:56.000000000 +0000
+@@ -67,6 +67,8 @@
+ size_t assoc_req_ies_len;
+ u8 *assoc_resp_ies;
+ size_t assoc_resp_ies_len;
++ u8 *scan_gen_ies;
++ size_t scan_gen_ies_len;
+ struct wpa_driver_capa capa;
+ int has_capability;
+ int we_version_compiled;
+@@ -501,7 +503,7 @@
+ {
+ union wpa_event_data data;
+
+- if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL)
++ if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL && drv->scan_gen_ies == NULL)
+ return;
+
+ os_memset(&data, 0, sizeof(data));
+@@ -515,14 +517,65 @@
+ drv->assoc_resp_ies = NULL;
+ data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len;
+ }
+-
++ if (drv->scan_gen_ies) {
++ data.assoc_info.beacon_ies = drv->scan_gen_ies;
++ drv->scan_gen_ies = NULL;
++ data.assoc_info.beacon_ies_len = drv->scan_gen_ies_len;
++ }
+ wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);
+
+ os_free(data.assoc_info.req_ies);
+ os_free(data.assoc_info.resp_ies);
++ os_free(data.assoc_info.beacon_ies);
+ }
+
+
++static void wpa_driver_wext_update_beacon_ies(struct wpa_driver_wext_data *drv,
++ const u8 *bssid)
++{
++#define SCAN_AP_LIMIT 128
++ struct wpa_scan_result *scan_res;
++ struct wpa_scan_result *r;
++ int num;
++ int i;
++
++ scan_res = os_malloc(SCAN_AP_LIMIT * sizeof(struct wpa_scan_result));
++ if (scan_res == NULL) {
++ wpa_printf(MSG_WARNING, "Failed to allocate memory for scan "
++ "results");
++ return;
++ }
++
++ num = wpa_driver_wext_get_scan_results(drv, scan_res, SCAN_AP_LIMIT);
++ if (num < 0) {
++ wpa_printf(MSG_DEBUG, "wpa_driver_wext_update_beacon_ies: failed to get scan results");
++ os_free(scan_res);
++ return;
++ }
++
++ /* Search for the current BSSID */
++ for (i = 0; i < num; i++) {
++ r = &scan_res[i];
++ if (os_memcmp(r->bssid, bssid, ETH_ALEN) != 0)
++ continue;
++
++ os_free(drv->scan_gen_ies);
++ drv->scan_gen_ies = os_malloc(r->wpa_ie_len + r->rsn_ie_len);
++ if (drv->scan_gen_ies == NULL) {
++ drv->scan_gen_ies_len = 0;
++ os_free(scan_res);
++ return;
++ }
++ os_memcpy(drv->scan_gen_ies, r->wpa_ie, r->wpa_ie_len);
++ os_memcpy(drv->scan_gen_ies + r->wpa_ie_len, r->rsn_ie, r->rsn_ie_len);
++ drv->scan_gen_ies_len = r->wpa_ie_len + r->rsn_ie_len;
++ wpa_hexdump(MSG_DEBUG, "wpa_driver_wext_update_beacon_ies:",
++ drv->scan_gen_ies, drv->scan_gen_ies_len);
++ }
++
++ os_free(scan_res);
++}
++
+ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
+ void *ctx, char *data, int len)
+ {
+@@ -577,6 +630,7 @@
+ NULL);
+
+ } else {
++ wpa_driver_wext_update_beacon_ies(drv, (const u8*)iwe->u.ap_addr.sa_data);
+ wpa_driver_wext_event_assoc_ies(drv);
+ wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
+ }
+@@ -1365,8 +1419,18 @@
+ case IWEVQUAL:
+ if (ap_num < max_size) {
+ results[ap_num].qual = iwe->u.qual.qual;
+- results[ap_num].noise = iwe->u.qual.noise;
+- results[ap_num].level = iwe->u.qual.level;
++
++ if( iwe->u.qual.updated & IW_QUAL_DBM )
++ {
++ /* Values in dBm, stored in u8 with range 63 : -192 */
++ results[ap_num].noise = ( iwe->u.qual.noise > 63 ) ? iwe->u.qual.noise - 0x100 : iwe->u.qual.noise;
++ results[ap_num].level = ( iwe->u.qual.level > 63 ) ? iwe->u.qual.level - 0x100 : iwe->u.qual.level;
++ }
++ else
++ {
++ results[ap_num].noise = iwe->u.qual.noise;
++ results[ap_num].level = iwe->u.qual.level;
++ }
+ }
+ break;
+ case SIOCGIWENCODE:
+diff -uNr wpa_supplicant-0.5.11/version.h wpa_supplicant-0.5.11_mod/version.h
+--- wpa_supplicant-0.5.11/version.h 2008-02-19 23:59:22.000000000 +0000
++++ wpa_supplicant-0.5.11_mod/version.h 2008-03-25 12:07:56.000000000 +0000
+@@ -1,6 +1,6 @@
+ #ifndef VERSION_H
+ #define VERSION_H
+
+-#define VERSION_STR "0.5.11"
++#define VERSION_STR "0.5.11-csr"
+
+ #endif /* VERSION_H */
diff --git a/unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.6.8_csr.patch b/unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.6.8_csr.patch
new file mode 100644
index 0000000..570c676
--- /dev/null
+++ b/unifi_hostsw_linux_147/unifi-linux/os_linux/wpa_supplicant/wpa_supplicant_0.6.8_csr.patch
@@ -0,0 +1,109 @@
+diff -uNr wpa_supplicant-0.6.8/src/drivers/driver_wext.h wpa_supplicant-0.6.8_mod/src/drivers/driver_wext.h
+--- wpa_supplicant-0.6.8/src/drivers/driver_wext.h 2008-02-19 23:59:22.000000000 +0000
++++ wpa_supplicant-0.6.8_mod/src/drivers/driver_wext.h 2008-03-25 12:07:56.000000000 +0000
+@@ -30,6 +30,8 @@
+ size_t assoc_req_ies_len;
+ u8 *assoc_resp_ies;
+ size_t assoc_resp_ies_len;
++ u8 *scan_gen_ies;
++ size_t scan_gen_ies_len;
+ struct wpa_driver_capa capa;
+ int has_capability;
+ int we_version_compiled;
+diff -uNr wpa_supplicant-0.6.8/src/drivers/driver_wext.c wpa_supplicant-0.6.8_mod/src/drivers/driver_wext.c
+--- wpa_supplicant-0.6.8/src/drivers/driver_wext.c 2008-02-19 23:59:22.000000000 +0000
++++ wpa_supplicant-0.6.8_mod/src/drivers/driver_wext.c 2008-03-25 12:07:56.000000000 +0000
+@@ -452,7 +452,7 @@
+ {
+ union wpa_event_data data;
+
+- if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL)
++ if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL && drv->scan_gen_ies == NULL)
+ return;
+
+ os_memset(&data, 0, sizeof(data));
+@@ -466,14 +466,54 @@
+ drv->assoc_resp_ies = NULL;
+ data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len;
+ }
+-
++ if (drv->scan_gen_ies) {
++ data.assoc_info.beacon_ies = drv->scan_gen_ies;
++ drv->scan_gen_ies = NULL;
++ data.assoc_info.beacon_ies_len = drv->scan_gen_ies_len;
++ }
+ wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);
+
+ os_free(data.assoc_info.req_ies);
+ os_free(data.assoc_info.resp_ies);
++ os_free(data.assoc_info.beacon_ies);
+ }
+
+
++static void wpa_driver_wext_update_beacon_ies(struct wpa_driver_wext_data *drv,
++ const u8 *bssid)
++{
++ struct wpa_scan_results *scan_res;
++ struct wpa_scan_res *r;
++ int i;
++ const u8 *ie_pos;
++
++ scan_res = wpa_driver_wext_get_scan_results(drv);
++ if (scan_res == NULL) {
++ wpa_printf(MSG_DEBUG, "wpa_driver_wext_update_beacon_ies: failed to get scan results");
++ return;
++ }
++
++ /* Search for the current BSSID */
++ for (i = 0; i < scan_res->num; i++) {
++ r = scan_res->res[i];
++ if (os_memcmp(r->bssid, bssid, ETH_ALEN) != 0)
++ continue;
++
++ ie_pos = (const u8 *) (r + 1);
++
++ wpa_hexdump(MSG_DEBUG, "wpa_driver_wext_update_beacon_ies:", ie_pos,
++ r->ie_len);
++ os_free(drv->scan_gen_ies);
++ drv->scan_gen_ies = os_malloc(r->ie_len);
++ if (drv->scan_gen_ies == NULL) {
++ drv->scan_gen_ies_len = 0;
++ return;
++ }
++ os_memcpy(drv->scan_gen_ies, ie_pos, r->ie_len);
++ drv->scan_gen_ies_len = r->ie_len;
++ }
++}
++
+ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
+ void *ctx, char *data, int len)
+ {
+@@ -527,6 +567,7 @@
+ NULL);
+
+ } else {
++ wpa_driver_wext_update_beacon_ies(drv, (const u8*)iwe->u.ap_addr.sa_data);
+ wpa_driver_wext_event_assoc_ies(drv);
+ wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
+ }
+
+@@ -1251,8 +1292,8 @@
+ struct wext_scan_data *res)
+ {
+ res->res.qual = iwe->u.qual.qual;
+- res->res.noise = iwe->u.qual.noise;
+- res->res.level = iwe->u.qual.level;
++ res->res.noise = ( iwe->u.qual.noise > 63 ) ? iwe->u.qual.noise - 0x100 : iwe->u.qual.noise;
++ res->res.level = ( iwe->u.qual.level > 63 ) ? iwe->u.qual.level - 0x100 : iwe->u.qual.level;
+ }
+diff -uNr wpa_supplicant-0.6.8/src/common/version.h wpa_supplicant-0.6.8_mod/src/common/version.h
+--- wpa_supplicant-0.6.8/src/common/version.h 2008-02-19 23:59:22.000000000 +0000
++++ wpa_supplicant-0.6.8_mod/src/common/version.h 2008-03-25 12:07:56.000000000 +0000
+@@ -1,6 +1,6 @@
+ #ifndef VERSION_H
+ #define VERSION_H
+
+-#define VERSION_STR "0.6.8"
++#define VERSION_STR "0.6.8-csr"
+
+ #endif /* VERSION_H */
diff --git a/unifi_hostsw_linux_147/versions.txt b/unifi_hostsw_linux_147/versions.txt
new file mode 100644
index 0000000..60a8fe4
--- /dev/null
+++ b/unifi_hostsw_linux_147/versions.txt
@@ -0,0 +1,3 @@
+oska=4
+sdioemb=15
+unifi_linux=147